使用useCallback vs在useEffect内部移动函数并移除依赖项



问题非常清楚,如标题所示,我想知道这两种不同的useEffect功能实现之间有什么具体的区别吗?

这里有一个例子:

const lookAtCameraPermission = async (status: CameraPermissionStatus): Promise<void> => {
switch (status) {
case 'authorized':
setIsCameraAllowed(true);
console.log('Camera permission granted.');
break;
case 'not-determined':
case 'denied':
setIsCameraAllowed(false);
console.log('Camera permission denied or not determined');
await requestCameraPermission();
break;
default:
setIsCameraAllowed(false);
throw new Error('Unknown camera permission status.');
}
};
useEffect(() => {
Camera.getCameraPermissionStatus().then(lookAtCameraPermission).catch(console.log);
}, [lookAtCameraPermission]);

当试图实现这样的东西时,ESLint说:The 'lookAtCameraPermission' function makes the dependencies of useEffect Hook (at line 66) change on every render. Move it inside the useEffect callback. Alternatively, wrap the definition of 'lookAtCameraPermission' in its own useCallback() Hook.eslintreact-hooks/exhaustive-deps

我更喜欢使用useCallback,但我不能确定这是实现这一点的最佳方式。

相关实施示例:https://github.com/facebook/react/issues/14920

您可以使用useRef钩子作为替代方法。例如:

const handlerRef = useRef(); 

handlerRef.current = async (status: CameraPermissionStatus): Promise<void> => {
switch (status) {
case 'authorized':
setIsCameraAllowed(true);
console.log('Camera permission granted.');
break;
case 'not-determined':
case 'denied':
setIsCameraAllowed(false);
console.log('Camera permission denied or not determined');
await requestCameraPermission();
break;
default:
setIsCameraAllowed(false);
throw new Error('Unknown camera permission status.');
}
}; 
useEffect(() => {
Camera.getCameraPermissionStatus().then(handlerRef.current).catch(console.log);
}, []);

然而,我仍然引用我们在useCallback中包装处理程序的方式,并将其作为useEffect的依赖项传递。

  • 第一个原因是我们不需要花很多时间思考将要更改的内容以将其置于依赖关系中
  • 其次,确保useEffect在必要时重新运行。如果handler使用了外部的变量,则useEffect钩子应在变量发生更改时重新执行

当我们错过dependencies中的任何项目时,这都是可怕的。

最新更新