查询减速器内部?还原

时间:2018-07-05 14:45:31

标签: javascript reactjs redux

如何在减速器中编写此代码以更改状态?

doc = {
  id:"zf123ada123ad",
  name:"examp",
  subdoc:{
    name:"subdoc examp",
    subsubdoc:[{
               id:"zcgsdf123zaar21",
               subsubsubdoc:[{
                             id:"af2317bh123",
                             value: "heyhey"   //this value I want to update
                            }]
              }]
}
}

假设我有一个看起来像这样的减速器 action.payload看起来像这样 { theInputId1:“ someId”, theInputId2:“ anotherId”, theInputValue:“ someValue” }

export function updateSubSubSubDoc(state = {}, action){
  switch(action.type){
    case 'UPDATE_THE_SUBSUBSUB':
      return {
               state.doc.subdoc.subsubdoc.find(x => x.id == 
          theInputId1).subsubsubdoc.find(x => x.id == theInputId2).value = theInputValue  // just example code for you to understand where i'm going.
             }

    default:
      return state
  }
}

我要执行的操作会在当前状态下更新一个subsubsub doc

1 个答案:

答案 0 :(得分:1)

使用ES6,这是您可以执行此操作的一种方式:

const initialState = { doc: { subdoc: { subsubdoc: {} } } };
export function doc(state = initialState, action) {
  switch (action.type) {
    case 'UPDATE_THE_SUBSUBSUB':
      const subsubdocIdx = state.doc.subdoc.
        subsubdoc.find(s => s.id == action.theInputId1);
      const subsubdoc = state.doc.subdoc.subsubdoc[subsubdocIdx];
      const subsubsubdocIdx = state.doc.subdoc.
        subsubdoc[subsubdocIdx].
        subsubsubdoc.find(s => s.id == action.theInputId2);
      const subsubsubdoc = state.doc.subdoc.
        subsubdoc[subsubdocIdx].
        subsubsubdoc[subsubsubdocIdx];
      return {
        ...state,
        doc: {
          ...state.doc,
          subdoc: {
            ...state.doc.subdoc,
            subsubdoc: [
              ...state.doc.subdoc.subsubdoc.slice(0, subsubdocIdx),
              {
                ...subsubdoc,
                subsubsubdoc: [
                  ...subsubdoc.slice(0, subsubsubdocIdx),
                  {
                    ...subsubsubdoc,
                    value: action.theInputValue,
                  },
                  ...subsubdoc.subsubsubdoc.slice(subsubsubdocIdx + 1, subsubdoc.subsubsubdoc.length - 1),
                ],
              },
              ...state.doc.subdoc.subsubdoc.slice(subsubdocIdx + 1, state.doc.subdoc.subsubdoc.length - 1),
            ]
          }
        }
      }
    default:
      return state;
  }
}

(我尚未测试此代码。)

该嵌套层与示例中的嵌套层相同,但是您可以考虑使用类似combineReducers的名称,以便于管理。前提是您还有其他操作可以一路创建文档链,并且您知道这些文档存在。

这是一个示例,您可能如何使用combineReducers来做到这一点:

function doc(state = {}, action) {
}

function subdoc(state = {}, action) {
}

function subsubdoc(state = [], action) {
}

function subsubsubdoc(state = [], action) {
  switch (action.type) {
    case 'UPDATE_THE_SUBSUBSUB':
      const idx = state.find(s => s.id == action.theInputId2);
      return [
        ...state.slice(0, idx),
        {
          ...state[idx],
          value: action.theInputValue,
        },
        ...state.slice(idx + 1),
      ];
    default:
      return state;
  }
}

export default combineReducers({
  doc,
  subdoc,
  subsubdoc,
  subsubsubdoc,
});

在此示例中,您不需要action.theInputId1,但是您需要在从子子文档到子子文档的数据中存储一些引用,以便在渲染时可以将其重新组合在一起。与其他所有图层相同。