我的意图是使用一个函数(由父组件接收,由useCallback
创建)作为useEffect
的依赖项,并且仅在函数更改时触发该效果。
考虑以下简单的组件:
function MyComponent(props) {
const [myState, setMyState] = useState(0);
useEffect(() => {
setMyState(props.calculate(1));
}, [props.calculate])
return <h1>{myState}</h1>;
}
接收props中的函数calculate
,并从中计算出myState
。然而,我得到了提示错误:
React Hook useEffect has a missing dependency: 'props'. Either include it or remove the dependency array.
我不明白为什么props.calculate
作为一个依赖是不够的,我们需要props
。我不想使用props
,因为这样每次渲染都会重新触发效果,即使calculate
没有改变。(假设calculate
已经在parent中使用useCallback
创建)。
下面的版本没有任何检查错误:
function MyComponentVersion2(props) {
const { calculate } = props;
const [myState, setMyState] = useState(0);
useEffect(() => {
setMyState(calculate(1));
}, [calculate])
return <h1>{myState}</h1>;
}
我的问题是:
- 为什么linter不适合
MyComponent
? MyComponent
和MyComponentVersion2
在语义上有区别吗?
我在codesandbox
中做了一个最小的例子谢谢!
这是因为调用props.calculate(1)
隐式地将props
作为this
值传递给calculate
,所以从技术上讲,结果可能取决于整个props
对象(参见此React问题)。对于解构后的calculate
调用,this
将是未定义的或全局对象,因此不依赖于props
。
您可以通过在calculate
的定义中用function (x) {console.log(this); return x + 1;}
替换(x) => {return x + 1;}
来看到两个组件之间的区别。