【问题标题】:Query inside reducer ? redux在减速器内部查询?还原
【发布时间】:2023-03-31 04:00:02
【问题描述】:

我如何在 reducer 中写这个来改变状态?

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: "另一个Id", 输入值:“一些值” }

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 文档

【问题讨论】:

  • 不清楚你如何代表国家。最初它是false,然后突然变成了具有doc.subdoc.subsubdoc 甚至具有where 方法的东西。
  • 复制时我打错字了
  • 我更新了,where方法没有实现。但它应该是一个在对象数组中通过 id 查找和对象的查询
  • 您的意思是findMDN
  • 这是一个很好的例子,说明为什么你的状态不应该深度嵌套。

标签: javascript reactjs redux


【解决方案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,但您需要在从 subsubdoc 到 subsubsubdoc 的数据中存储一些引用,以便在渲染时可以将其重新组合在一起。与所有其他层相同。

【讨论】:

  • 这么多的嵌套表明它需要重构。
  • 100% 同意。我会在自己的代码中使用combineReducers 将其分解为更小的减速器。
  • 那会是什么样子?
  • 添加了一个编辑,该编辑显示了如何使用combineReducers 使用较浅的结构来执行此操作的示例。
  • 非常感谢@EricLevine!
猜你喜欢
  • 1970-01-01
  • 2018-07-09
  • 2020-04-14
  • 1970-01-01
  • 2011-10-04
  • 1970-01-01
  • 2017-12-24
  • 2017-05-17
  • 2015-11-27
相关资源
最近更新 更多