bad*_*oks 8 reactjs react-hooks
我想在作为第一个参数传递给useReducer. 这是因为我的 reducer 函数依赖于多个switch(首先操作,然后是水果类型)。
我查过“嵌套减速器”,但这些问题的解决方案似乎都与 redux 和 相关combineReducers,其中没有与 Hooks 等效的。
演示代码(即使 codeandbox 再次关闭):
它实际上并没有显示在代码和框中(因为沙箱本身不能正常工作)但是在我自己的机器上Uncaught TypeError: fruits.apples.map is not a function我点击添加按钮后得到。但是,在此之前,map工作正常,所有项目都按预期呈现。
for*_*d04 12
您的代码中有一些错误,例如,class而不是className,缺少key属性。我修改了你的样本,看看这里。
减速器是纯函数也很重要- 当更改由合适的操作触发时总是返回一个新状态,不要改变以前的状态(和嵌套属性)。如果没有reducer不能处理动作,就返回之前的状态——不要把reducer扔进去,这也会让它变得不纯。
您的形状的另一种选择是让每个子减速器负责整个状态树的某些子状态,以使其更具可扩展性和可组合性(Link)。所以一个用于苹果的减速器,一个用于香蕉和一个橙子(首先是水果类型,然后是操作)。但原则上,您可以按照自己的意愿/需要处理形状。
希望,这有帮助。
如果您寻求类似 Redux 的combineReducersfor实现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"));Run Code Online (Sandbox Code Playgroud)
<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>Run Code Online (Sandbox Code Playgroud)
use*_*133 10
那些来这里寻找钩子combineReducers()函数的人useReducer(),这可能对你有帮助
const combineReducers = (...reducers: Function[]) =>
(state: any = initialState, action: any): any => {
for(let i=0;i<reducers.length;i++)
state = reducers[i](state, action)
return state;
}
Run Code Online (Sandbox Code Playgroud)
将此用作
// At module level, so the combined function doesn't change.
const combinedReducer = combineReducers(reducer1, reducer2);
// Inside your component.
const [state, dispatch] = useReducer(combinedReducer, initialState)
Run Code Online (Sandbox Code Playgroud)
编辑:我最近喜欢减少功能,我认为它的实现方式更干净
const combineReducers = (...reducers) =>
(state, action) =>
reducers.reduce((newState, reducer) =>
reducer(newState, action), state)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5475 次 |
| 最近记录: |