#reactjs #react-router
#reactjs #реагировать-маршрутизатор
Вопрос:
Насколько я знаю, эффект использования может быть вызван следующими условиями
- зависимости меняются
- Изменение маршрута
- Начальный рендеринг
У меня есть следующий компонент, data
это сложный объект. Когда он вызывается изменением маршрута, data
prop имеет кэшированное значение. Все остальное, такое как состояние, ссылка, сбрасывается.
const App = memo(({ data }}) => {
useEffect(() => {
// if triggered by route change, do thing
}, [data]);
return (<div />)
});
Каков наилучший способ определить, вызывается ли useEffect изменением маршрута?
Ответ №1:
Попробуйте поставить location
как зависимость:
useEffect(() => {
// ...
}, [location]);
Редактировать
Если вы хотите исключить эту зависимость, вы можете сделать:
const [flag, setFlag] = useState(true);
useEffect(() => {
setFlag(false);
}, [location]);
useEffect(async () => {
await setTimeout(() => undefined, 500); //sleep to wait for other useEffect() to set a flag or not
if (flag) { /* do sth that is not invoked by a location change */ }
else {
setFlag(true);
}
}, [data]);
правка2
Я просмотрел это в официальных документах https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state
Таким образом, вы можете создать componentDidUpdate(prevProps)
перехват, чтобы ваш код выглядел примерно так:
function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
useEffect(() => {
const prevLocation = usePrevious(location);
if (location === prevLocation)
//the body of your function
}, [data]);
Комментарии:
1. Только что протестированный, он все еще срабатывает при изменении маршрута.
2. @user3908406 Хорошо, я понял, что вы хотите вызвать его при изменении местоположения… Исключение зависимости в useEffect() не так просто, но я добавил ее в редактирование своего ответа, вы можете попробовать.
3. Проголосовал за вас. Спасибо. Все еще ищу лучшее решение. тот, который не нуждается в другом useEffect или state или ref, был бы отличным, поскольку мне нужно сделать это во многих компонентах
4. Я пробовал этот подход раньше, но при изменении маршрута usePrevious ref сбрасывается, поэтому prevLocation будет неопределенным.
5. Я думаю, что это происходит только тогда, когда вы обновляете браузер (или вручную вводите путь в поле адреса), и это то, что React не контролирует по определению (хотя, возможно, вы найдете какое-то обходное решение в Интернете).