当前位置: 首页 > 面试题库 >

挂钩:使用useReducer时结合多个减速器?

昌乐生
2023-03-14
问题内容

我想使用嵌套化简器,而不是在作为第一个参数传递给的主化简器中使用嵌套的switch语句(甚至可以这样做?)useReducer。这是因为我的减速器功能取决于多个switch(第一个操作,然后是水果类型)。

我查找了“嵌套的简化器”,但是这些问题的解决方案似乎都与redux和combineReducers挂钩,而Hooks却没有。

演示代码(即使codesandbox再次关闭):

它实际上并没有显示在codesandbox中(因为沙箱本身无法正常工作),但是在我自己的计算机上Uncaught TypeError: fruits.apples.map is not a function,单击Add按钮后得到了。但是,在此之前,map可以正常工作,并且所有项目均按预期方式呈现。


问题答案:

您的代码中有一些错误,例如缺少class而不是属性。我修改了您的示例,在这里看看。className``key

简化器是纯函数,也很重要-
当通过适当的操作触发更改时,始终返回新状态,而不会使先前的状态(和嵌套属性)发生变化。如果没有reducer无法处理该操作,则只需返回先前的状态-
不要抛出reducer,这也将使其变得不纯。

形状的替代方法是让每个子级减速器负责整个状态树的某些子状态,以使其更具可伸缩性和可组合性(Link)。因此,一种还原剂可用于苹果,一种还原剂可用于香蕉和一种橙子(第一种水果类型,然后操作)。但原则上,您可以根据需要/形状来处理形状。

希望能帮上忙。

更新:

如果您寻求combineReducersfor
的类似Redux的实现useReducer,也可以看看Lauri的答案,尽管我建议在大多数情况下使用不同的实现。在以下示例中,每个化简器仅获得其状态的自己的部分(“切片”),这降低了其复杂性。您还可以很好地扩展此解决方案-只需添加一个新的属性+ reducer:

// combine reducers ala Redux: each can handle its own slice
const combineReducers = slices => (prevState, action) =>
  // I like to use array.reduce, you can also just write a for..in loop 
  Object.keys(slices).reduce(
    (nextState, nextProp) => ({
      ...nextState,
      [nextProp]: slices[nextProp](prevState[nextProp], action)
    }),
    prevState
  );

// atomar reducers only get either apple or orange state
const apples = (state, action) => action.type === "ADD_APPLE" ? state + 1 : state;
const oranges = (state, action) => action.type === "ADD_ORANGE" ? state + 1 : state;

const App = () => {
  const [state, dispatch] = React.useReducer(
    combineReducers({ apples, oranges }), // here we create the reducer slices
    { apples: 0, oranges: 0 }
  );
  const handleAddApple = () => dispatch({ type: "ADD_APPLE" });
  const handleAddOrange = () => dispatch({ type: "ADD_ORANGE" });

  return (
    <div>
      <p>Apples: {state.apples}, Oranges: {state.oranges}</p>
      <button onClick={handleAddApple}>add Apple</button>
      <button onClick={handleAddOrange}>add Orange</button>
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));


<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js" integrity="sha256-32Gmw5rBDXyMjg/73FgpukoTZdMrxuYW7tj8adbN8z4=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js" integrity="sha256-bjQ42ac3EN0GqK40pC9gGi/YixvKyZ24qMP/9HiGW7w=" crossorigin="anonymous"></script>
<div id="root"></div>


 类似资料:
  • 我试图创建一个简单的组件,从Apollo GraphQL服务器(查询)返回我的所有组织。我想从一个上下文状态呈现所有这些组织,在这个上下文状态下,在组件挂载(由useEffect挂钩处理)之后,可以使用分派方法放置这些组织。 如果状态结果(organizations数组)为空,useEffect钩子应该调用函数getOrganizations,然后调用自定义钩子useGetOrganization

  • 上面的测试示例不起作用,但用于演示我试图实现的目标。并实际呈现0 div,因为组件中声明的初始状态包含0项。 > 为了测试的目的,我应该如何修改一个reducer的状态或者更改它部署时的initialState? 我习惯于在多个组件中使用Redux还原程序,但是useReducer需要一个传递的initialState。。。这就提出了一个问题:react-hook的reducer是作为一个实例通过

  • 我有一个使用输入钩子组件,其工作原理如下: 它获取一个(input,inputName)并返回一个挂钩的输入组件。当我想动态地改变视图中现有输入的可见性时,我得到一个错误:渲染的钩子比之前渲染的多。

  • 我有一个简单的地图减少工作,我正在建立反向索引。 我的映射器工作正常(我检查过了),并输出了word和docID:TFIDF值的密钥对: 映射器(仅显示输出): 化简器的唯一工作是组合这些值。这是我的实现: 然而,它没有组合任何东西,输出看起来基本上与来自映射器的相同。输出中有一些行具有相同的键,尽管reducer应该将它们组合起来——基本上,使用reducer时,输出文件中的所有键都应该是唯一的

  • 问题内容: 随着AngularJS V1.7的发布,已经不建议使用和取消预定义绑定的选项: 由于38f8c9, 指令绑定在构造函数中不再可用 。 迁移代码: * 如果指定,则需要首先迁移代码,以便将标志翻转到。有关如何执行此操作的说明,请参见 “从1.5迁移到1.6”指南。之后,删除该语句。 — AngularJS开发人员指南- 迁移至V1.7-编译 由于bcd0d4的缘故,默认情况下在控制器实例

  • 当我试图在我的MR工作中使用合并器时,我得到了下面的异常 Java . lang . nullpointerexception < br > at org . Apache . Hadoop . mapred . ifile$writer . append(ifile . Java:193)< br > at org . Apache . Hadoop . mapred . task$combin