#reactjs #react-hooks
#reactjs #реагирующие хуки
Вопрос:
Отказ от ответственности: я не считаю следующий подход хорошей практикой. Вероятно, я могу или должен использовать useEffect
вместо этого, но я все еще хочу оценить правильность существующего кода.
В контексте хуков и функциональных компонентов верно ли следующее предположение?
{
setState(newValue);
setTimeout(() => {
//Here code expects that re-rendering of all components affected by changing state has been completed.
}, 0);
}
Могу ли я быть уверен, что повторный рендеринг был завершен после setTimeout
или это не гарантировано?
-
Верно ли это предположение для текущей версии React? Если нет, есть ли какое-то конкретное поведение, нарушающее его?
-
Могут ли на это повлиять предстоящие изменения React?
Ответ №1:
Это не гарантируется. Чтобы гарантировать, что ваше состояние изменилось, вам нужно будет использовать useEffect
следующее
useEffect(() => {
// do something now that state has changed
}, [state])
Комментарии:
1. Спасибо, но есть ли конкретная причина, почему это не так, или пример, показывающий это?
2. Согласно документации React «Если вы знакомы с методами жизненного цикла класса React, вы можете представить себе useEffect Hook как componentDidMount , componentDidUpdate и componentWillUnmount вместе взятые». Таким образом, он срабатывает при обновлении компонента, гарантируя, что состояние изменилось.
3. Я знаком с
useEffect
этим, это хорошее решение, но мой вопрос прагматичен: учитывая, что у меня уже есть код, написанный с использованиемsetTimeout
way, есть ли какие-либо оговорки или крайние случаи, когда он не работает описанным способом?4. Ах, ну, я думаю, здесь было бы предостережение, если бы изменение состояния когда-либо занимало больше 0 секунд. Тогда ваш код внутри
setTimeout
может использовать устаревшее состояние. Так что нет, вы не можете быть уверены. И вы, вероятно, захотите провести рефакторинг, чтобы быть в безопасности.5. @AlDuncanson это неверно.
setTimeout
задержка в 0 секунд не означает 0 секунд. Это означает минимум ноль секунд, без какого-либо максимального времени. Это просто означает, что этот обратный вызов будет извлечен из очереди при следующей полной очистке стека. Поскольку обратный вызов помещается в очередь после запроса обновления состояния, если все состояние обновляется синхронно, setTimeout гарантирует, что повторный рендеринг выполнен. Просто имейте в виду, поскольку значения закрытия фиксируются, использование любого значения состояния всегда будет устаревшим. Итак: это хак, используйтеuseEffect
.