React - 添加 props.something 作为 useEffect 的依赖项

Teh*_*ila 7 javascript destructuring reactjs react-props react-hooks

我这里有这个 useEffect 代码:

useEffect(() => {
    if (status === "completed" && !error) 
      props.onAddedComment();
  }, [status,error,props.onAddedComment]);
Run Code Online (Sandbox Code Playgroud)

但我在终端中收到此警告: React Hook useEffect 缺少依赖项:“props”。包含它或删除依赖项数组。但是,当任何prop 更改时,“props”也会更改,因此首选修复方法是在 useEffect 调用之外解构“props”对象,并引用 useEffect 内的那些特定 props

props.onAddedComment如果我传递的是而不是整个 props 对象,为什么需要使用解构?即使我添加了,它仍然会引用整个道具吗.onAddedComment

params我对这段代码中使用 , 有同样的问题:

useEffect(() => {
    sendRequest(params.quoteId);
  }, [params.quoteId, sendRequest]);
Run Code Online (Sandbox Code Playgroud)

我在这里没有收到此警告,为什么?

简而言之,我的问题是,即使我在.somethingprops 之后添加,我是否应该始终使用解构,以及为什么它不使用参数警告我。

谢谢!

Cer*_*nce 6

感谢安德鲁斯找到了这个。看这里

当您将函数作为对象的一部分调用时,即使函数本身没有改变,行为函数也可能取决于正在使用的对象。这是一个最小的例子来说明原因

useEffect(() => {
  obj.fn();
}, [obj.fn]);
Run Code Online (Sandbox Code Playgroud)

可能是一个问题:

useEffect(() => {
  obj.fn();
}, [obj.fn]);
Run Code Online (Sandbox Code Playgroud)
const Child = ({ obj }) => {
  React.useEffect(() => {
    obj.fn();
  }, [obj.fn]);
  return null;
};
const App = () => {
  console.log('App rendering');
  const [count, setCount] = React.useState(0);
  // This fn is stable across renders
  const [fn] = React.useState(() => function() { console.log('count is', this.count); });
  React.useEffect(() => {
    setTimeout(() => {
      console.log('Calling setCount; expecting obj.fn to be called again');
      setCount(count + 1);
    }, 1000);
  }, []);
  return <Child obj={{ count, fn }} />
};

ReactDOM.render(<App />, document.querySelector('.react'));
Run Code Online (Sandbox Code Playgroud)

Exhaustive-deps 的目的是让您在回调内的任何内容发生变化时调用效果回调。因为理论上,如果对象具有方法,则对对象的更改可能会导致执行的逻辑发生更改,因此应该将对象本身添加到依赖项数组中。

这不会产生错误:

useEffect(() => {
  sendRequest(params.quoteId);
}, [params.quoteId, sendRequest]);
Run Code Online (Sandbox Code Playgroud)

因为quoteId不是您正在调用的函数;与我上面的代码片段和您的原始代码相比, of 并不重要,在这种情况下, a ofthis理论上可能很重要。paramsthisprops

如果你这样做了

useEffect(() => {
  sendRequest(params.getQuoteId());
}, [params.getQuoteId, sendRequest]);
Run Code Online (Sandbox Code Playgroud)

这会产生警告,因为现在调用getQuoteId取决于params是什么。

从对象中删除函数并将函数放入独立标识符中也会消除警告,因为将函数作为独立标识符而不是对象的一部分调用会消除函数对对象的可能依赖关系 - 在函数内部this没有不再引用该对象,但是undefined.

一种思考方式是,当您将函数作为对象的一部分调用时,对象本身将作为隐藏的附加参数传递给函数,就像this函数内部一样。

这:

useEffect(() => {
  obj.fn();
}, [obj.fn]);
Run Code Online (Sandbox Code Playgroud)

就像做

const { obj } = fn;
useEffect(() => {
  fn.call(obj)
}, [fn]);
Run Code Online (Sandbox Code Playgroud)

这显然是缺少obj依赖项 - 即使 的实现根本fn不考虑它。this