停止useEffect在挂载上运行

时间:2019-12-26 19:26:15

标签: reactjs react-redux react-hooks use-effect

我只希望useEffect在我的依赖项列表更改时运行,每次安装组件时它也正在运行,有什么方法可以在安装时不触发吗?

  

如果某些值,您可以告诉React跳过应用效果   重新渲染之间没有变化。

我最初以为这意味着它不应该在随后的安装中重新渲染,而是this question cleared that up.

我在母版“页面”(反应路由器)中显示记录列表,用户可以选择单个记录并转到详细信息页面,然后返回到母版页面-因此,母版列表组件为在这种情况下完全卸载/安装。而且,每次加载“母版页”时,我都会看到正在获取的数据,我只希望在其中一个依赖项发生更改时发生这种情况。这些依赖项和数据本身存储在Redux中,因此它们是全局的。

是否可以使useEffect或其他挂钩仅在依赖项更改时触发?

const {page, pageSize, search, sorts} = useSelector(getFilters);
const data = useSelector(getData);

useEffect(() => {

  console.log("fetching");
  dispatch(fetchData(page, pageSize, search, sorts));

}, [page, pageSize, search, sorts]);

2 个答案:

答案 0 :(得分:1)

您不能直接配置它。

但是,常见的模式是像这样使用一些isMounted标志:

const useFetchNotOnMount = () => {
  const { page, pageSize, search, sorts } = useSelector(getFilters);
  const dispatch = useDispatch();
  const data = useSelector(getData);

  const isMounted = useRef(false);

  useEffect(() => {
    if (isMounted.current) {
      console.log('fetching');
      dispatch(fetchData(page, pageSize, search, sorts));
    } else {
      isMounted.current = true;
    }
  }, [page, pageSize, search, sorts]);
};

答案 1 :(得分:0)

如果您有多个 useEffect 需要在最初阻止运行,您可以执行以下操作:


export default function App() {
  const mountedRef = useMountedRef();
  const [isLoggedIn, setLoggedIn] = React.useState(false);
  const [anotherOne, setAnotherOne] = React.useState(false);

  React.useEffect(() => {
    if (mountedRef.current) {
      console.log("triggered", isLoggedIn);
    }
  }, [isLoggedIn]);

  React.useEffect(() => {
    if (mountedRef.current) {
      console.log("triggered", anotherOne);
    }
  }, [anotherOne]);

  React.useEffect(() => {
    if (mountedRef.current) {
      console.log("triggered", isLoggedIn, anotherOne);
    }
  }, [anotherOne, isLoggedIn]);

  return (
    <div>
      <button onClick={() => setLoggedIn(true)}>Login</button>
    </div>
  );
}

const useMountedRef = () => {
  const mountedRef = React.useRef(false);

  React.useEffect(() => {
    setTimeout(() => {
      mountedRef.current = true;
    });
  }, []);

  return mountedRef;
};

演示:https://stackblitz.com/edit/react-eelqp2

有一点很重要,您必须使用 setTimeout 进行合理的延迟,以确保在所有初始 useEffects 之后将 ref 值设置为 true。