Хук React useState, по-видимому, не обновляет состояние при явном вызове функции установки - PullRequest
0 голосов
/ 24 марта 2020

Это код, написанный

function App() {

  const [number, setNumber] = useState(1);
  const mapper = {
    1: 'One',
    2: 'two',
    3: 'three'
  }
  const setFirst = () => {
    setNumber(1);
    console.log(number);
    console.log(mapper[number]);
  }
  const setSecond = () => {
    setNumber(2);
    console.log(number);
    console.log(mapper[number]);
  }
  const setThird = () => {
    setNumber(3);
    console.log(number);
    console.log(mapper[number]);
  }
  return (
    <div>
      <button onClick={() => { setFirst(); }}>One</button>

      <button onClick={() => { setSecond() }} >Two</button>

      <button onClick={() => { setThird(); }} >Three</button>
    </div>
  );
}

Ожидаемый: при нажатии setFirst() число должно быть установлено на 1. При нажатии setSecond() число должно быть установлено на 2. При нажатии на setThird(), число должно быть установлено на 3.

Что происходит,

При последовательном нажатии setFirst() -> setSecond() -> setThird() в повторяющемся режиме

Вывод:

1
One
1
One
2
Two
3
Three
1
One

Ожидаемый результат:

1
One
2
Two
3
Three
1
One
2
Two

Может кто-нибудь помочь мне с этим. Мне нужна помощь в выяснении, где ошибка.

Ответы [ 2 ]

1 голос
/ 25 марта 2020

Как сказал Крис в комментарии, setNumber - это асинхронная функция, поэтому ее обновление не отображается сразу после выполнения.

Более того, вы должны знать, что при каждом рендеринге каждый метод внутри Компонент "сложен" внутри своего текущего закрытия. Позвольте мне уточнить:

  1. Вы визуализируете компонент, который возвращает button (предположим, только первый). Когда button визуализируется, поскольку setFirst связано с ним, вы можете представить себе некое подобие создаваемой комнаты, в которую копируются все внешние переменные, используемые внутри setFirst. Таким образом, поскольку setFirst использует переменные number и mapper, в этой "комнате" создается их копия;
  2. Когда вы наконец нажимаете setFirst, вы запускаете setNumber. Это setNumber делает НЕ обновление number внутри setFirst комнаты, но обновляет number, который будет использоваться на следующей фазе рендеринга;

Этот пример поможет вам понять, почему, когда вы нажимаете setSecond, вы регистрируетесь 1 One : когда метод setSecond был инициализирован для этого рендера, number был все еще 1.

0 голосов
/ 25 марта 2020

Когда функция установки в eventl oop. есть асинхронная функция. Вы можете позволить быть sync функцией. но в основном мы не рекомендуем делать это, поэтому я предпочитаю использовать callback для этого.

setNumber(2, () => {
  console.log('');
})

Anti-Pattern Syn c way

Promise.resolve().then(() => {
  setNumber(2);
  console.log(2);
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...