【问题标题】:Why my custom hook causes infinite data refetching?为什么我的自定义挂钩会导致无限数据重新获取?
【发布时间】:2020-04-16 15:36:26
【问题描述】:

我的组件从查询字符串中获取散列 ID,然后使用该散列调用 api 以获取帖子以供审核。

eslint 强制我将自定义挂钩添加到依赖数组。

  fetchpost();
  }, [query]);

但是这样做会导致无限循环。为了阻止它,我需要禁用这个 eslint 规则,如下所示。

// component file 
  const history = useHistory();
  const dispatch = useDispatch();
  const query = useQuery();
  const [post, setPost] = useState(null);
  const [hash, setHash] = useState(null);

  useEffect(() => {
    const fetchpost = async () => {
      const hash = query.get("hashed_id");
      const post = await fetchReviewPost(
        `/api/posts/${hash}/review`
      );
      setHash(hash);
      setPost(post);
    };

    fetchpost();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

// utils file 
import { useLocation } from "react-router-dom";

export const getCurrentURL = () => {
  return document.URL;
};

export const useQuery = () => {
  const queryString = useLocation().search;

  return new URLSearchParams(queryString);
};

丹·阿布拉莫夫写信An infinite loop may also happen if you specify a value that always changes in the dependency array.

这里是这样吗? query 的引用在每次渲染时都不同吗?以及为什么 eslint 要把它放在一个依赖数组中?

他还说 removing a dependency you use (or blindly specifying []) is usually the wrong fix. 我通过禁用 eslint 规则来做到这一点。

有什么想法吗?

【问题讨论】:

  • useQuery 来自 react-apollo 还是你的自定义钩子?

标签: reactjs react-hooks use-effect


【解决方案1】:

如果你真的想继续坚持 eslint 的建议并使用 useQuery 钩子,这里有另一种方法:

  // component file 
  const history = useHistory();
  const dispatch = useDispatch();
  const q = useQuery();
  const [query] = useState(q);
  const [post, setPost] = useState(null);
  const [hash, setHash] = useState(null);

  useEffect(() => {
    const fetchpost = async () => {
      const hash = query.get("hashed_id");
      const post = await fetchReviewPost(
        `/api/posts/${hash}/review`
      );
      setHash(hash);
      setPost(post);
    };

    fetchpost();
  }, [query]);

此时query 值在后续函数调用中保持不变。

但是,我会删除 useQuery 挂钩,并将其内容直接放入 fetchpost 函数中。

【讨论】:

  • 那行得通 :) 当我认为查询在每个渲染上都有不同的引用从而导致重新渲染时,我是对的吗?
  • 完全正确。比较是通过引用进行的。
猜你喜欢
  • 2021-09-29
  • 2021-10-26
  • 1970-01-01
  • 2020-06-20
  • 2022-10-09
  • 1970-01-01
  • 2023-01-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多