简体   繁体   English

我应该如何删除“ React Hook useEffect缺少依赖项”警告?

[英]How should i remove warning “React Hook useEffect has a missing dependency”?

i have a function that use in useEffect and click event, then throw warning "React Hook useEffect has a missing dependency", how should i remove the warning? 我有一个在useEffect和click事件中使用的函数,然后引发警告“ React Hook useEffect具有缺少的依赖项”,我应如何删除警告?

// location is react router location
const Component = ({ location }) => {
  const [data, setData] = useState(null);

  const fetchData = () => {
    const { id } = parseLocation(location);
    fetchDataFromServer(id).then(data => setData(data));
  }

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

  return (
    <div>
      {data}
      <button onClick={fetchData)}>reload</button>
    </div>
  );
}

then i try this, but the warning still exist 然后我尝试这个,但警告仍然存在

// location is react router location
const Component = ({ location }) => {
  const [data, setData] = useState(null);

  const fetchData = (l) => {
    // l is location
    const { id } = parseLocation(l);
    fetchDataFromServer(id).then(data => setData(data));
  }

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

  return (
    <div>
      {data}
      <button onClick={() => fetchData(location)}>reload</button>
    </div>
  );
}

The point of the exhaustive-deps rule is to prevent hooks from reading stale props or state. exhaustive-deps规则的目的是防止挂钩读取陈旧的道具或状态。 The issue is that since fetchData is defined within the component, as far as the linter is concerned, it could be accessing stale props or state (via closure). 问题在于,由于fetchData是在组件内定义的,就fetchData而言,它可能正在访问过时的props或状态(通过闭包)。

One solution is to pull fetchData out of the component and pass it everything it needs: (it's already being passed the location): 一种解决方案是将fetchData从组件中拉出,并将它需要的所有内容传递给它:(它已经通过了位置):

const fetchData = (l, setData) => {
  // l is location
  const { id } = parseLocation(l);
  fetchDataFromServer(id).then(data => setData(data));
}

const Component = ({ location }) => {
  const [data, setData] = useState(null);

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

  return (
    <div>
      {data}
      <button onClick={() => fetchData(location, setData)}>reload</button>
    </div>
  );
}

Since fetchData isn't defined outside the component, the linter knows that it won't access state or props, so it isn't an issue for stale data. 由于fetchData不在组件外部定义,因此linter知道它不会访问状态或道具,因此对于陈旧数据而言这不是问题。


To be clear, though, your original solution is correct , from a runtime perspective, since fetchData doesn't read state or props - but the linter doesn't know that. 不过要明确一点,从运行时的角度来看,您的原始解决方案是正确的 ,因为fetchData不会读取状态或fetchData -但是fetchData不知道。

You could simply disable the linter, but it'd be easy to accidentally introduce bugs later on (if fetchData is ever modified) that way. 您可以简单地禁用linter,但是稍后以这种方式(如果曾经修改fetchData )不小心引入错误很容易。 It's better to have the linter rule verifying correctness, even if it means some slight restructuring of code. 最好使linter规则验证正确性,即使这意味着对代码进行一些轻微的重组。


Alternative solution 替代解决方案

An alternative solution which leverages closure instead of passing the location into fetchData : 一种替代方法,该方法利用闭包而不是将位置传递到fetchData

const Component = ({ location }) => {
  const [data, setData] = useState(null);

  const fetchData = useCallback(() => {
    // Uses location from closure
    const { id } = parseLocation(location);
    fetchDataFromServer(id).then(data => setData(data));

  // Ensure that location isn't stale
  }, [location]);

  useEffect(() => {
    fetchData();

  // Ensure that fetchData isn't stale
  }, [fetchData]);

  return (
    <div>
      {data}
      <button onClick={fetchData}>reload</button>
    </div>
  );
}

This approach lets you avoid passing location into fetchData every time you call it. 这种方法使您避免每次调用时都将location传递给fetchData However, with this approach it's important to make sure to avoid stale state and props. 但是,使用这种方法时,务必确保避免过时的状态和道具。

If you omitted the [fetchData] dep to useEffect , the effect would only run once, and new data wouldn't be fetched when location changed. 如果您将[fetchData] dep省略为useEffect ,则效果将仅运行一次,并且在location更改时不会获取新数据。

But if you have fetchData in the deps for useEffect but don't wrap fetchData in useCallback , the fetchData function is a new function every render, which would cause the useEffect to run every render (which would be bad). 但是,如果您在fetchData的deps中有useEffect但没有在useCallback包装fetchData ,则fetchData函数是每个渲染的新函数,这将导致useEffect运行每个渲染(这很不好)。

By wrapping in useCallback , the fetchData function is only a new function whenever the location changes, which causes the useEffect to run at the appropriate point. 通过包装useCallback ,只要location发生变化, fetchData函数就只是一个新函数,这会导致useEffect在适当的位置运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 React Hook useEffect 缺少依赖项:'setValid'。 如何删除此警告 - React Hook useEffect has a missing dependency: 'setValid' . How to remove this warning 我应该如何修复 eslint 警告(React Hook useEffect 缺少依赖项)和由警告引起的循环? - How should I fix eslint warning (React Hook useEffect has a missing dependency) and a loop caused by the warning? 警告:React Hook useEffect 缺少依赖项 - warning: React Hook useEffect has a missing dependency React useEffect 钩子缺少依赖项警告 - React useEffect hook has a missing dependency warning React Hook useEffect 缺少依赖项警告 - React Hook useEffect has a missing dependency warning 如何修复这个“React Hook useEffect has a missing dependency”警告? - How to fix this “React Hook useEffect has a missing dependency” warning? 如何解决此警告:“React Hook useEffect 缺少依赖项:'history'”? - How to fix this warning: “React Hook useEffect has a missing dependency: 'history'”? 如何删除“React Hook useEffect has missing dependencies”警告 - How to remove the “React Hook useEffect has missing dependencies” warning 当 deps 为 [] 时,React 警告 React Hook useEffect 缺少依赖项 - React warning React Hook useEffect has a missing dependency when the deps are [] &#39;React Hook useEffect has an missing dependency&#39; 警告功能 - 'React Hook useEffect has a missing dependency' warning with function
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM