我在代码框上链接了一个示例应用程序,它增加了一个计数器来显示问题。
当您使用useReducer增加值时,它会以应有的方式登录到控制台中。
但是,当您增加第二个值时(这次是使用useState ),它也会登录到控制台中,尽管我从未明确告诉过它。
只有在同一个组件中有useReducer和useState时,才会发生这种情况。
如何使它不使用useState记录控制台中的状态?
我知道我可以比较状态,但是在我的应用程序中,状态是一个嵌套很深的对象,如果它存在的话,我宁愿找到另一个解决方案。
有什么想法吗?
const initialState = { valueWithUseReducer: 0 };
const useReducerWithLogger = (...args) => {
const prevState = useRef(initialState);
const [state, dispatch] = useReducer(...args);
console.log("Prev state: ", prevState.current);
console.log("Next state: ", state);
prevState.current = state;
return [state, dispatch];
};
const Reducer = (state = initialState, action) => {
switch (action.type) {
case "INCREMENT_WITH_USE_REDUCER":
return {
valueWithUseReducer: state.valueWithUseReducer + 1
};
default:
return state;
}
};
function App() {
const [state, dispatch] = useReducerWithLogger(Reducer, initialState);
const [valueWithUseState, setValueWithUseState] = useState(0);
return (
<div className="App">
<p>Value With useReducer: {state.valueWithUseReducer}</p>
<button onClick={() => dispatch({ type: "INCREMENT_WITH_USE_REDUCER" })}>
Increment with useReducer
</button>
<p>Value With useState: {valueWithUseState}</p>
<button onClick={() => setValueWithUseState(valueWithUseState + 1)}>
Increment with useState
</button>
</div>
);
}
发布于 2019-08-25 12:48:09
您的代码按预期工作:
<button onClick={() => setValueWithUseState(valueWithUseState + 1)}>
Increment with useState
</button>
在单击button
时,将执行更改状态、App
重新呈现和函数体的组件。
Building 定制钩子 useReducerWithLogger
相当于:
/*
const useReducerWithLogger = (...args) => {
const prevState = useRef(initialState);
const [state, dispatch] = useReducer(...args);
console.log('in reducer');
prevState.current = state;
return [state, dispatch];
};
*/
function App() {
const prevState = useRef(initialState);
const [state, dispatch] = useReducer(reducer,initialState);
console.log('in reducer');
prevState.current = state;
...
return ...
}
因此,您可以注意到,在每个呈现上都将执行console.log
。
“理想情况下,当使用useState时,它不会将状态记录在控制台中,而只在使用useReducer时才会记录状态”。
只有当状态更改时,您才能通过reducer
日志记录来修复它:
const useReducerWithLogger = (...args) => {
const prevState = useRef(initialState);
const [state, dispatch] = useReducer(...args);
prevState.current = state;
useEffect(() => {
console.log('in reducer');
}, [state]);
return [state, dispatch];
};
https://stackoverflow.com/questions/57649426
复制