分派后直到下一次渲染后才反映最新状态

时间:2020-01-14 23:19:08

标签: reactjs state react-context

我在React状态管理上遇到了麻烦。 我想在单击按钮后使用Context API更新全局状态,然后使用更新后的状态执行其他操作。

按钮将操作分配到全局状态。但是,当我尝试立即读取状态后,所做的更改将在应用程序重新渲染后才会反映出来。

const App = () => {
  const playerRef = useRef();
  const { state, addPlayers } = useContext(playerContext);

  // subscribe playerRef changes to global state,
  useEffect(() => {
    playerRef.current = state;
    console.log("players #", playerRef.current.length);
  }, [state]);

  const add = useCallback(() => {
    // dispatch an add players action to the store
    addPlayers([{ name: "new" }, { name: "newer" }]);

    // PROBLEM: Need latest state value here after dispatch
    // but it's not immediately reflected here
    console.log("player # after dispatch ", playerRef.current.length);

    // do something with the new state
  }, [playerRef, addPlayers]);

  const handleSubmit = () => {
    add();
  };

  return (
    <div>
      <p>Players: {String(state.map(player => player.name))}</p>
      <button type="button" onClick={handleSubmit}>
        AddPlayers
      </button>
    </div>
  );
};

export default App;

这是控制台显示的内容。 enter image description here

link到codesandbox即可查看完整的应用程序。 谢谢。

1 个答案:

答案 0 :(得分:0)

您正在尝试在状态更新后立即读取playerRef.current的值:

  const add = useCallback(() => {
    addPlayers([{ name: "new" }, { name: "newer" }]);
    console.log("player # after dispatch ", playerRef.current.length);
  }, [playerRef, addPlayers]);

但是,直到运行以下效果,playerRef.current的值才会更新:

  useEffect(() => {
    playerRef.current = state;
    console.log("players #", playerRef.current.length);
  }, [state]);

useCallback通话结束后很快就会发生**

您应该改为读取state的值。引用应用作实例变量,以捕获以后要读取的值;对于他们来说,这不是一个很好的用例。您尝试要做的基本上是这样的:

  const { state, addPlayers } = useContext(playerContext);
  const playerRef = React.useRef();
  playerRef.current = state;

可能是:

  const { state: currentPlayer, addPlayers } = useContext(playerContext);

*这可能不太准确,但是无论哪种方式,您都是都取决于比赛条件。