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

我正在编写一个react应用程序redux,避免使用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>

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


德玛西亚99
浏览 127回答 1
1回答

守着星空守着你

看起来您的组件在每个渲染周期都订阅了商店,并且由于订阅回调更新了组件状态,因此触发了另一个渲染周期。您可能只希望组件订阅您的商店一次。您可以使用效果订阅一次以在更新时记录状态。使用效果清理功能取消订阅。const App = () => {&nbsp; const [val, setVal] = React.useState(0);&nbsp; handleClick = () => {&nbsp; &nbsp; store.dispatch({type: 'INCREMENT'})&nbsp; }&nbsp; useEffect(() => {&nbsp; &nbsp; const unsubscribe = store.subscribe(() => {&nbsp; &nbsp; &nbsp; const state = store.getState();&nbsp; &nbsp; &nbsp; console.log("Listener is called", state.count);&nbsp; &nbsp; &nbsp; setVal(state.count);&nbsp; &nbsp; });&nbsp; &nbsp; /* unsubscribe() */;&nbsp; &nbsp; return unsubscribe; // <-- return cleanup function&nbsp; }, []); // <-- empty dependency array to run once on mount&nbsp; return (&nbsp; &nbsp; <div>&nbsp; &nbsp; &nbsp; <span>{val}</span>&nbsp; &nbsp; &nbsp; <button onClick={handleClick}>Click</button>&nbsp; &nbsp; </div>&nbsp; );}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript