Последнее состояние не отображается после отправки до следующего рендера - PullRequest
0 голосов
/ 15 января 2020

У меня проблемы с управлением состоянием 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

ссылка на коды и окно, чтобы увидеть полное приложение. Спасибо.

1 Ответ

0 голосов
/ 15 января 2020

Вы пытаетесь прочитать значение 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. Ссылки должны использоваться в качестве переменных экземпляра для захвата значений, которые будут считаны позднее; это не очень хороший вариант использования для них. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * '' 10 '* * * * * * * *' ', возможно, это не так. точно, но в любом случае, вы будете в зависимости от состояния гонки, делая это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...