首页 文章

React redux normalizr:如何处理嵌套实体?

提问于
浏览
5

假设我有一个这样的结构,这是从API获取并在我的实体上使用“normalizr”的结果:

entities: {
    users:{
        1: {
            name: 'John',
            posts: [ 1, 4 ]
        }
    },
    posts: {
        1: {
            name: 'First Post',
        },
        4: {
            name: 'Second Post',
        }
    }
}

现在我有一个按用户过滤帖子的方法,基本上可以这样做:

let filteredPosts = {};
entities.users.posts.forEach(key => {
    if(posts.hasOwnProperty(key))
        filteredPosts[key] = posts[key]
});

以及显示该用户帖子的页面,例如:

render() {
    return(
        <div>
            {Object.keys(filteredPosts).map(key => {
                return (
                    <div>{filteredPosts[key].name}</div>
                );
            })}
        </div>
    )
}

我的实体reducer非常简单:

import { merge } from 'lodash';
...
function entities(state = { users: {}, posts: {} }, action) {
    if (action.response && action.response.entities) {
        return merge({}, state, action.response.entities);
    }
    return state;
}

现在,如果我向API请求为该用户添加帖子,返回新创建的帖子记录,该记录将自动添加到我的实体上的帖子中 .

我如何处理更新用户以反映该更改,以便用户现在有3个帖子,数组中有新的帖子ID?

我应该创建一个reducer并听取post创建操作,并在那里更新 state.entities.users.posts 吗?重新获取实体似乎不是一种选择 . 最好的方法是什么?

谢谢

更新:

这是我现在必须使用的解决方案,以保持数据的一致性 . 我修改了对帐户创建的帖子ID的回复 . 我知道这可以分解为多个reducers,但我仍然想知道是否有更好更直接的方法,我不必为每个嵌套实体执行此操作 .

function entities(state = {}, action) { 
    ...

    if(action.type === 'POST_ADD_SUCCESS') {
        // Get the user id from the created post
        let userId = response.entities.posts[response.result].userId;
        // Add the user with all his posts to the response
        response.entities.users = {
            [userId]: {
                posts: [...state.users[userId].posts, response.result]
            }
        }
    }
    ...
    // Merge normally
    return merge({}, state, response.entities);
}

3 回答

  • 0

    为什么不使用normalizr作为中间件而不是自己动手?像https://github.com/wbinnssmith/redux-normalizr-middleware之类的东西

  • 0

    您是否考虑在API成功发布时使用格式化实体调度新操作?

    const foo = (entities) => { 
      type: "POST_ADD_SUCCESS"
      response : { entities }
    }
    

    操作类型无关紧要,因为您的实体reducer无论如何都会截取操作

  • 1

    您更新的代码段主要沿着正确的路径显示,尽管我仍然在那里引用"response" . 您的动作创建者函数可能应该抓取用户ID和帖子ID,并且当AJAX调用成功时,创建一个看起来像 {type : POST_ADD_SUCCESS, userId : userId : postId} 的动作 . 换句话说,减速器不应该是't know anything about a 404556 at all, just that it should add post ID ' x ' to the list for user ID ' y' .

相关问题