我正在尝试对自定义挂钩有一个基本的了解。我目前有一个parent
组件和一个自定义钩子来处理它的一些逻辑。我的自定义挂钩看起来像:
export const useTrip = () => {
const origin = useSelector((store) =>
store.trip.origin
)
const destination = useSelector((store) =>
store.trip.destination
)
const [waypoints, setWaypoints] = useState([])
const [value, setValue] = useState(null)
useEffect(() => {
expensiveFunction()
}, [origin, destination])
const getMidpoints = (value) => {
...
setWaypoints(result)
}
console.log("this triggers way more times than expected")
const expensiveFunction = () => {
...
setValue(result)
}
return { getMidpoints, waypoints, value }
}
我的自定义钩子里有更多的东西,但我的自定义挂钩似乎是";重新渲染";太多次了,正如我在console.log
中看到的那样,这个自定义挂钩被重新绘制是有原因的吗?
EDIT:经过更多的测试,如果我的useEffect
钩子的依赖项发生了变化,那么整个自定义钩子就会重新运行,我会再次看到我的console.log
行。这是自定义挂钩的正确行为吗?或者我用错了
您应该考虑要运行的自定义挂钩的功能总是,或者只要react喜欢运行它。
只有传递给钩子内useEffect
调用的函数才会被调用(即,如果依赖关系发生变化(。
因此,是的,可以钩子内的console.log
被调用这么多次(假设主函数被调用这么多次是正确的(。
心理模型
你可以把它(作为一个心理模型(想象成你的自定义钩子的整个内容在您的主要功能中,例如:
const useMyHook = () => {
console.log('this line was ivoked');
useEffect(()=>{
console.log('useEffect was ivoked');
});
};
const Main = ( props ) => {
useMyHook();
return <>nothing</>
};
行为与大致相同
const Main = ( props ) => {
console.log('this line was ivoked');
useEffect(()=>{
console.log('useEffect was ivoked');
});
return <>nothing</>
};
如何理解钩子调用
您不应该依赖于钩子函数本身的运行时间和频率,相反,您应该只依赖于react给你的保证,比如:
- 如果,或
- 如果…,将调用此useEffect函数
较小的挂钩
你说"我的定制挂钩里还有很多东西">。我建议把你的定制挂钩拆成更小的定制挂钩。