解决 next中的“React Hook useEffect has missing dependencies”

225 阅读2分钟

在项目中,使用useEffect中去获取数据,useEffect(()=>{},[])如果第二个参数是空数组,默认是dom渲染完后,就执行一次Hook函数。项目中很容易提示一些错误React Hook useEffect has missing dependencies: 'lang' and 'search'.本文就针对这种现象,列举一些解决方法

1、useEffect

  • 第一个参数:是指定一个副效应函数,组件每渲染一次,该函数就自动执行一次。如果副效应函数返回一个函数,组件卸载后,会执行该返回的函数
  • 第二个参数:使用一个数组指定副效应函数的依赖项,只有依赖项发生变化,才会重新渲染
    • 不传第二个参数,每次渲染都执行第一个函数
    • 传[],表示只执行一次函数
    • 传[lang,search],其中一个参数发生变化,才重新执行函数

2、原因

React Hook useEffect has missing dependencies:不是 React 错误,而是 ESLint 错误。ESLint 提供了专门针对 React 的插件,其中包含一组旨在帮助开发人员编写更好的 React 代码的规则。这些规则之一是"react-hooks/exhaustive-deps"检测“React Hook useEffect 缺少依赖项”错误的规则

3、解决

a、 添加包括所有缺少的依赖项(lang、search)

  useEffect(() => {
    async function fetchData() {
      if (search) {
        setLoading(true);
        try {
          const searchs = await getSearch(lang, search, false);
          setSearchSimilarContents(searchs);
        } catch (error) {
          console.warn(error);
        }
        setLoading(false);
      }
    }
    fetchData();
  }, [lang, search]);

b、禁用eslint规则,只执行一次

  useEffect(() => {
    async function fetchData() {
      if (search) {
        setLoading(true);
        try {
          const searchs = await getSearch(lang, search, false);
          setSearchSimilarContents(searchs);
        } catch (error) {
          console.warn(error);
        }
        setLoading(false);
      }
    }
    fetchData();
// eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

c、使用对象或者函数时候,使用useMemo,useCallback,或者useEffect中声明使用

  • 1、为了解决React Hook useEffect has missing dependencies,单纯添加fetchData作为依赖,而出现错误的实列(原因:在JavaScript中,对象和数组通过引用进行比较,并每次都指向内存中的不同位置,它的值将在每次渲染时发生变化,从而导致无限的重新渲染循环)
//单纯添加依赖,出现死循环错误案列
  async function fetchData() {
    try {
      const searchGuess = await getSearchGuess(lang, searchQuery ?? "", false);
      setSearchGuess(searchGuess);
    } catch (error) {
      console.warn(error);
    }
  }

  useEffect(() => {
    fetchData();
  }, [fetchData]);

image.png

  • 2、直接放在useEffect中,声明请求函数
  useEffect(() => {
    async function fetchData() {
      try {
        const searchGuess = await getSearchGuess(
          lang,
          searchQuery ?? "",
          false
        );
        setSearchGuess(searchGuess);
      } catch (error) {
        console.warn(error);
      }
    }
    fetchData();
  }, []);
  • 3、使用useCallback,依赖的lang、searchQuery发生变化,函数才会变化
  const fetchData = useCallback(async () => {
    try {
      const searchGuess = await getSearchGuess(lang, searchQuery ?? "", false);
      setSearchGuess(searchGuess);
    } catch (error) {
      console.warn(error);
    }
  }, [lang, searchQuery]);

  useEffect(() => {
    fetchData();
  }, [fetchData]);

总结:针对这种“React Hook useEffect 缺少依赖项,不能为了解决问题就单纯添加依赖,而是要具体分析使用情况,选择最佳方法来处理

4、参考