我在下面链接了我在codesandbox上制作的示例应用程序,它增加了一个计数器来显示问题。
当您使用 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>
);
}
最佳答案
您的代码按预期工作:
<button onClick={() => setValueWithUseState(valueWithUseState + 1)}>
Increment with useState
</button>
单击按钮
后,您的组件会更改状态,App
重新渲染,并执行函数体。
建筑物a custom hook 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
。
"Well ideally, it would not log the state in the console when using useState, only when using 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];
};
关于javascript - Hook useState 在不应该记录状态时记录状态。包含示例代码盒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57649426/