#reactjs #react-hooks #use-effect #usecallback
#reactjs #реагирующие крючки #use-effect #usecallback
Вопрос:
У меня есть разбитый на страницы список данных, которые я обновляю на основе фильтра и смещения (страницы) При обновлении смещения (следующая / предыдущая страница) Я нажимаю на API и получаю новые данные. Когда фильтр обновляется, я сбрасываю смещение на 0.
Проблема в том, что когда фильтр обновляется и обновляется смещение, это приводит к тому, что useEffect запускается дважды. Который, в свою очередь, дважды вызывает api.
const [filter, setFilter] = useState('All');
const [offset, setOffset] = useState(0);
onFilterChange = (value) => {
setFilter(value);
offset !== 0 amp;amp; setOffset(0);
}
getDataFromAPI = useCallback(() => {
const endpoint = `https://example.com/data?filter=${filter}amp;offset=${offset}`;
CallApi(endpoint);
}, [offset, filter])
useEffect(getDataFromAPI, [getDataFromAPI]);
Ответ №1:
Я думаю, что исправлением было бы избавиться useEffect
в таком случае. Иногда это используется без необходимости. Просто вызовите CallApi
внутри обработчиков onFilterChange
and onOffsetChange
с новыми значениями, которые были установлены, и все.
Вот несколько соответствующих цитат из Дэна Абрамова:
Оглядываясь назад, я лично убежден, что если какой-то эффект не может безопасно сработать (например, сработать дважды вместо одного раза), возникает проблема. Обычно вещи, которые не могут сработать, связаны с действиями пользователя («купить», «отправить», «завершить»). Действия начинаются в обработчиках событий. Используйте их!
Подводя итог, если что-то произойдет из-за того, что пользователь что-то сделал, useEffect может быть не лучшим инструментом.
С другой стороны, если эффект просто синхронизирует что-то (координаты Google Map на виджете) с текущим состоянием, useEffect — хороший инструмент. И он может безопасно перегореть.
PS Но просто для того, чтобы отметить, что я думал, что в вашем случае react выполнит два разных вызова set state внутри обработчика изменения фильтра (следовательно, вызовет render один раз), но, похоже, это не так? В любом случае вы все равно можете предпочесть удалить рекомендацию в начале моего ответа useEffect
.
Комментарии:
1. У меня есть useEffect, потому что мне нужно, чтобы это срабатывало при первом рендеринге, а затем срабатывало только при изменении смещения / фильтра. Если я удалю useEffect, как мне заставить это сработать при первоначальном рендеринге?
2. @Shawnnortrop Оставьте
useEffect
, но укажите его [] в качестве зависимостей, а также вам может потребоваться отключить линтер, используя » // eslint-disable-next-line react-hooks / исчерпывающий-deps».3. Спасибо, это имеет смысл, я могу удалить зависимость от useEffect, странно, что я не получаю сообщение об ошибке о зависимости. Однако я только что понял, что поведение не такое, как я описал. Он вызывает API дважды, однако первый вызов — это вызов параметров. Я должен был посмотреть немного ближе. Спасибо за цитаты из Абрамова, я думаю, что это ценная информация, и я могу рассмотреть рефакторинг в соответствии с вашей рекомендацией