Я новичок в реагировании на хуки и столкнулся с ситуацией, которую я решил, но не уверен, что это правильная реализация useEffect. У меня есть форма с некоторыми полями (ответ, вопрос и т. д.) с некоторой проверкой, но без реализации useEffect ниже моя проверка была на один шаг позади из-за асинхронного характера настройки состояния. После добавления useEffect и элементов состояния в массив зависимостей useEffect это было исправлено. Но побочным эффектом добавления элементов в этот массив был повторный рендеринг, и, следовательно, fetchData запускался каждый раз при изменении состояния. Каждый раз, когда выборка данных завершалась, она стирала измененное состояние любых элементов, которые я изменял в форме.
Моим решением была «смонтированная» переменная состояния, которая устанавливается в значение true, когда происходит выборка. Затем, если смонтировано было верно, я больше не получаю. Это решение, по-видимому, устранило проблему повторной загрузки, а также состояние, отстающее на один шаг. Это правильный шаблон для использования или есть лучший/более предпочтительный способ?
const [mounted, setMounted] = useState(false)
useEffect(() => {// reactive state
// if params.id that means we need to edit an existing faq
if (params.id && !mounted){
async function fetchData() {
await fetchFaqs();
setMounted(true);
}
fetchData();
}
checkIfFormIsValid();
}, [answer, question, section, sort, checkIfFormIsValid]);
Спасибо за комментарий. Да, с этим кодом данные извлекаются только один раз.





Вы можете просто использовать отдельные useEffect вот так:
// add params.id to dependency array
useEffect(() => {
if (params.id) {
async function fetchData() {
await fetchFaqs();
}
fetchData();
}
}, [params.id])
useEffect(() => {
checkIfFormIsValid();
}, [answer, question, section, sort, checkIfFormIsValid])
Спасибо Энес. Интересный. Я пришел из мира componentDidMount, поэтому думал об использовании useEffect только один раз.
Вы, вероятно, захотите кэшировать эти данные, а не получать их при каждом рендеринге, даже если вам удалось предотвратить слишком много повторных рендерингов. Одним из быстрых и простых способов реализации является использование асинхронного селектора RecoilJS. См. пример асинхронности здесь: recoiljs.org/docs/guides/asynchronous-data-queries