疑惑
在使用react-hooks/exhaustive-deps校验依赖时,有一个困惑点。
当我在useEffect的回调函数中使用了obj.fn()时,在依赖中必须要把obj作为依赖,当我只把obj.fn作为依赖时,就会出现“missing dependencies”的warning,这个逻辑我有点不太理解。
const useLoading = () => {
const [loading, setLoading] = useState(false)
const start = useCallback(() => {
setLoading(true)
}, [])
const stop = useCallback(() => {
setLoading(false)
}, [])
return {
loading,
start,
stop,
}
}
const Demo = () => {
const loading = useLoading()
useEffect(() => {
loading.start()
Promise.resolve([])
.then(console.log)
.finally(() => {
loading.stop
})
}, [loading.start, loading.stop])
return <div>this is demo</div>
}
eslint给了一个报错,要求我必须把loading加入依赖中,但是在useLoading hook中,返回的整个loading对象是不稳定的,因此在依赖中把loading作为依赖的话,就会引发effect hook里回调函数的执行
类似的,下面的case同样会触发warning
const Demo = (props: { foo: () => void }) => {
useEffect(() => {
props.foo()
}, [props.foo])
return <div>this is demo</div>
}
上述问题的解决方案,其实目前我已经找到了,我只是不太理解为什么不能按照上面的方式写,看了下规则的代码,但很无奈,有点看不懂,希望有大佬能给个答案,不胜感激。
解决方案
可以把函数解构出来,然后在useEffect中去调用,如下:
只是说,如果在一个比较复杂的组件里,需要多次用到useLoading hook,那就需要考虑命名冲突问题了
import React, { useState, useCallback, useEffect } from 'react'
const useLoading = () => {
const [loading, setLoading] = useState(false)
const start = useCallback(() => {
setLoading(true)
}, [])
const stop = useCallback(() => {
setLoading(false)
}, [])
return {
loading,
start,
stop,
}
}
const Demo = () => {
const {loading, start, stop} = useLoading()
useEffect(() => {
start()
Promise.resolve([])
.then(console.log)
.finally(stop)
}, [start, stop])
return <div>this is demo</div>
}
export default Demo