我在这里有这个useEffect代码:
useEffect(() => {
if (status === "completed" && !error)
props.onAddedComment();
}, [status,error,props.onAddedComment]);
但是我在终端中得到这个警告:React Hook useEffect缺少一个依赖项:'props'。要么包含它,要么删除依赖项数组。然而,当任何prop改变时,'props'也会改变,所以最好的解决方法是在useEffect调用之外解构'props'对象,并在useEffect
中引用那些特定的props。为什么我需要使用解构,如果我传递props.onAddedComment
,而不是整个道具对象?即使我添加了.onAddedComment
,它仍然是指整个道具吗?
我有同样的问题与使用params
,在这个代码:
useEffect(() => {
sendRequest(params.quoteId);
}, [params.quoteId, sendRequest]);
我在这里没有得到这个警告,为什么呢?
简而言之,我的问题是,如果我应该总是使用解构,即使我在道具后添加.something
,为什么它没有用参数警告我。
谢谢!
感谢Andrius找到这个。看到这里。
当你作为对象的一部分调用一个函数时,行为函数也可能取决于正在使用的对象,即使函数本身没有改变。这里有一个最小的例子说明为什么
useEffect(() => {
obj.fn();
}, [obj.fn]);
可能是一个问题:
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'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>
精疲力竭-深度的目的是让你在回调内部发生变化时调用效果回调。因为从理论上讲,如果对象有方法,对对象的更改可能会在执行的逻辑中产生更改,因此应该将对象本身添加到依赖项数组中。
这不会产生错误:
useEffect(() => {
sendRequest(params.quoteId);
}, [params.quoteId, sendRequest]);
因为quoteId
不是你调用的函数;params
的this
并不重要,与我上面的代码片段和你的原始代码相比,在这种情况下,props
的this
理论上可能很重要。
如果你做了
useEffect(() => {
sendRequest(params.getQuoteId());
}, [params.getQuoteId, sendRequest]);
这会产生警告,因为现在getQuoteId
的调用取决于params
是什么。
将函数从对象中删除并将函数放入独立标识符中也会删除警告,因为将函数作为独立标识符而不是作为对象的一部分调用,可以消除函数对对象的可能依赖性——函数内部的this
不再引用对象,而是引用undefined
。
可以这样理解:当你作为对象的一部分调用一个函数时,对象本身作为一个隐藏的附加参数传递给函数,就像函数内部的this
一样。
:
useEffect(() => {
obj.fn();
}, [obj.fn]);
就像做
const { obj } = fn;
useEffect(() => {
fn.call(obj)
}, [fn]);
显然缺少作为依赖的obj
——即使fn
的实现根本不考虑它的this
。
别这么用,
首先在函数中传递props。例如,您的函数看起来像👇
const App = ({onAddedComment}) => {
}
then,在useEffect函数
useEffect(() => {
if (status === "completed" && !error)
props.onAddedComment();
}, [status,error,onAddedComment]);
你可以在参数的情况下这样做。
我想你应该试试这个。也告诉我这是否有效。