Состояние React Hooks не работает должным образом, когда вызывающая его функция вызывается в другой функции - PullRequest
2 голосов
/ 06 апреля 2019

У меня есть этот компонент, использующий крючки:

function App() {
  const [text, setText] = useState({ h1: "hello", h2: "hi" });

  const changeH1 = () => {
    setText({
      ...text,
      h1: text.h1 + "C"
    });
  };

  const changeH2 = () => {
    setText({
      ...text,
      h2: text.h2 + "X"
    });
  };

  const changeAll = () => {
    changeH1();
    changeH2();
  };

  return (
    <div className="App">
      <h1 onClick={() => changeH1()}>{text.h1}</h1>
      <h1 onClick={() => changeH2()}>{text.h2}</h1>
      <button onClick={() => changeAll()}>Change</button>
    </div>
  );
}

Он будет отображать два заголовка с текстом и кнопкой. Когда я нажимаю на первый заголовок, символ «C» будет добавлен к заголовку. Когда я нажимаю на второй заголовок, символ «X» будет добавлен к заголовку. Когда я нажимаю кнопку, он выполняет два действия одновременно.

Отлично работает на двух заголовках, кроме кнопки. Когда я нажимаю кнопку, меняется только второй заголовок. Я думаю, что setText из changeH1 и changeH2 не работают, когда они вызываются в changeAll. Что не так с моим кодом?

1 Ответ

1 голос
/ 06 апреля 2019

Поскольку changeH2() перезаписывает свойство h1, делая ...text.

2 setText() вызовы выполняются перед повторным рендерингом - я полагаю, это из-за пакетирования, как объяснено в https://overreacted.io/react-as-a-ui-runtime/#batching

Решением было бы использование простого состояния вместо объекта:

  const [h1, setH1] = useState("hello");
  const [h2, setH2] = useState("hi");
  ...

Или useReducer для более сложных операций https://reactjs.org/docs/hooks-reference.html#usereducer

...