繁体   English   中英

为什么我的回调使用 redux 多次调用

[英]Why my callback is calling multiple time with redux

我正在使用redux编写一个react应用程序,避免使用react-redux ,如果我们手动处理所有分派的事件,这在技术上是可行的。 这是示例代码。

index.html

<!DOCTYPE html>
<html>
<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.6.0/redux.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.1/react.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.1/react-dom.js"></script>
</head>
<body>
  <div id="app"></div>
  <script>

  const appState= {
    count: 0,
  }

  const reducer = (state, action) => {
    if (typeof state === 'undefined') state = appState;
    switch (action.type) {
      case 'INCREMENT':
        return {count: state.count+1}
      case 'DECREMENT':
        return {count: state.count-1}
      default:
        return state
    }
  }

  var store = Redux.createStore(reducer);

  const App = () => {
    const [val, setVal] = React.useState(0);
  
    handleClick = () => {
      store.dispatch({type: 'INCREMENT'})
    }
  
    const unsubscribe = store.subscribe(() => {
      const state = store.getState();
      console.log("Listener is called")
      setVal(state.count);
    });
  
    /* unsubscribe() */;
  
    return (
      <div>
        <span>{val}</span>
        <button onClick={handleClick}>Click</button>
      </div>
    );
  }
  ReactDOM.render(<App />, document.querySelector("#app"))
  </script>
</body>
</html>

在这里,如果我第一次单击按钮将日志打印到控制台一次,但是当我第二次单击按钮时它会在日志上打印两次语句,这表明来自订阅的回调被调用两次,为什么会发生我怎样才能防止这种情况发生?

看起来您的组件在每个渲染周期都订阅了 store,并且由于订阅回调更新了组件状态,因此触发了另一个渲染周期。

您可能只希望该组件订阅一次您的商店。

您可以使用效果订阅一次以在更新时记录状态。 使用效果清理功能退订。

const App = () => {
  const [val, setVal] = React.useState(0);

  handleClick = () => {
    store.dispatch({type: 'INCREMENT'})
  }

  useEffect(() => {
    const unsubscribe = store.subscribe(() => {
      const state = store.getState();
      console.log("Listener is called", state.count);
      setVal(state.count);
    });

    /* unsubscribe() */;
    return unsubscribe; // <-- return cleanup function
  }, []); // <-- empty dependency array to run once on mount

  return (
    <div>
      <span>{val}</span>
      <button onClick={handleClick}>Click</button>
    </div>
  );
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM