问题非常清楚,如标题所示,我想知道这两种不同的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
中的任何项目时,这都是可怕的。