首页 > 解决方案 > 如何区分useEffect是否被路由改变触发

问题描述

据我所知,useEffect 可以由以下条件触发

  1. 依赖改变
  2. 路线变更
  3. 初始渲染

我有以下组件,data是一个复杂的对象。当它被路由更改触发时,dataprop 具有缓存值。其他所有内容,例如 state、ref 都会被重置。

const App = memo(({ data }}) => {
  useEffect(() => {
     // if triggered by route change, do thing
     
  }, [data]);

  return (<div />)
});

区分路由更改是否调用 useEffect 的最佳方法是什么?

标签: reactjsreact-router

解决方案


尝试将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]);

推荐阅读