Как определить, вызван ли эффект использования изменением маршрута

#reactjs #react-router

#reactjs #реагировать-маршрутизатор

Вопрос:

Насколько я знаю, эффект использования может быть вызван следующими условиями

  1. зависимости меняются
  2. Изменение маршрута
  3. Начальный рендеринг

У меня есть следующий компонент, 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 не контролирует по определению (хотя, возможно, вы найдете какое-то обходное решение в Интернете).