javascript - Hook useState 在不应该记录状态时记录状态。包含示例代码盒

标签 javascript reactjs react-hooks

我在下面链接了我在codesandbox上制作的示例应用程序,它增加了一个计数器来显示问题。

当您使用 useReducer 增加值时,它会按应有的方式记录在控制台中。

但是当您增加第二个值时,这次是使用 useState,它也会记录在控制台中,即使我从未明确告知它。

只有当您在同一组件中使用 useReducer 和 useState 时,才会发生这种情况。

如何使其不使用 useState 在控制台中记录状态?

我知道我可以比较状态,如果它们匹配,则不记录,但在我的应用程序中,状态是一个深层嵌套的对象,我宁愿找到另一个解决方案(如果存在)。

有什么想法吗?

Edit gifted-dan-mbjuq

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];
};

Edit Q-57649426-LogOnReducerState

关于javascript - Hook useState 在不应该记录状态时记录状态。包含示例代码盒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57649426/

相关文章:

javascript - 如何防止样式百分比出现 "URIError: malformed URI sequence"

javascript - 切换在 react 中不起作用,没有错误

javascript - 不同类别的状态变化(不 react )

reactjs - 测试一个使用 Resize Observer 的 React Hook

javascript - 使用 useRef Hook 将副本复制到剪贴板

javascript - 在 javascript 中将 _{number} 与正则表达式匹配

javascript - 在使用 JavaScript 更改 CSS 类时转义正斜杠 ("/")

javascript - 如何记录 "catched"异常?

reactjs - Apollo Client 如何将本地缓存的突变发送到服务器

javascript - react Hook : Invalid hook call while using useQuery