从redux中的reducer中获取ID

时间:2016-06-06 17:56:29

标签: javascript reactjs redux react-redux redux-thunk

我很新,并尝试使用react& amp来构建一个简单的书签应用程序终极版。

我无法解决这个问题:

用户可以创建一个书签并将其添加到多个文件夹。因此,如果文件夹已存在,我会发送addMark(bookmark)操作,之后addMark(folder)editFolder(folder)。如您所见,书签和文件夹是通过相同的操作添加的,因为在我的状态树中,它们都只是标记 - 通过其类型属性进行区分。

我的问题:如何告诉文件夹对象哪个新书签要添加到书签的文件夹列表?如何在两个调度之间检索新创建的书签的ID?

解决方案我觉得不满意:

  1. 我知道如何在reducer中生成书签ID(通过Math.max在现有的书签ID上),这样我就可以在2个调度之间重现新的书签ID。这听起来像是一个糟糕的黑客。 / LI>
  2. 书签和文件夹保存在同一个状态分支(相同的缩减器)中,因为它们都只是“标记”,我可以有一个引用最新添加的书签的状态属性,但这听起来也像是一个糟糕的黑客
  3. 一些源代码,了解我的内容:

    // mapping between dispatcher and props to my react view
    const mapDispatchToProps = (dispatch) => ({
      saveMark: (mark) => {
        if (mark.id) {
          dispatch(editMark(mark));
        } else {
          dispatch(addMark(mark));
        }
      },
    });
    export default connect(mapStateToProps, mapDispatchToProps)(AddMark);
    

    在AddMark内部,它是容器组件:

    // save the bookmark first
    this.props.saveMark({
          type: 'bookmark',
          title: this.state.title,
          url: this.state.url,
          icon: this.props.icon,
          style: this.state.style,
     });
     // now I need the bookmark ID
     folders.forEach(folder => {
        folder.children.push(bookmarkID) // <-- !!!
     });
     folders.forEach(folder => this.props.saveMark(folder));
    

    我找不到令人满意的解决方案。

2 个答案:

答案 0 :(得分:3)

我认为你应该只在这里调度一个动作:addBookmark(),它接受​​书签对象和文件夹。

处理将书签对象添加到文件夹中的代码应该是reducer的一部分。

另外,请参阅Redux项目中的Todos example。它在动作创建中提供了id,使其可以在组件中读取它。您还可以使用当前状态来计算最新ID:

function addBookmark(bookmark, folder) {
   return (dispatch, getState) => {
       const newBookmark = Object.assign({
         id: Math.max(0, ...getState().bookmarks.map(b => b.id)) + 1,
       }, bookmark);
       dispatch({
         type: 'ADD_BOOKMARK',
         bookmark: newBookmark,
         folder: folder
       });
   }
}

请注意,该示例需要redux-thunk中间件来分派这些操作。

然后,您可以访问文件夹reducer中带有id的书签

function folderReducer(state = [], action) {
  if(action.type === 'ADD_BOOKMARK') {
     return state.map(folder => {
       if(folder === action.folder) {
         return Object.assign({}, folder, {children: [...folder.children, action.bookmark.id]}
       }
       return folder;
     })
  }
  //another reducer code
  return state;
} 

答案 1 :(得分:0)

Reducers正在操纵你商店的实例。您可以使用getState()

显示您所在州的当前快照