无法在 useEffect 中使用来自反应导航的 "useIsFocused()" 作为依赖项来设置状态
Can't setState inside useEffect with "useIsFocused()" from react-navigation as dependency
我使用 react-navigation/native
中的 useIsFocused()
函数作为 useEffect
的依赖来监听屏幕焦点,所以当我返回时它进入 if
isFocused
和 myRoute.params.isChecked
来执行函数。
但它不会更新 setRoute(newRoute);
和 setIsLoading(false)
上的路由状态。函数内的 setIsLoading(true)
被调用,但 useEffect 路由内的那个没有被调用,因为它从不调用路由更新。因此,屏幕一直在无限加载。
为什么它不更新 isLoading
和 route
状态?
import React, { useEffect, useState } from 'react';
import { useFocusEffect, useIsFocused } from '@react-navigation/native';
const MyRoute = ({ navigation, route: myRoute }) => {
const [route, setRoute] = useState({});
const [isLoading, setIsLoading] = useState(true);
const isFocused = useIsFocused();
/** ... */
useEffect(() => {
console.log('route call')
if (Object.keys(route).length) {
setIsLoading(false);
}
}, [route]);
useEffect(() => {
console.log(isLoading);
}, [isLoading]);
useEffect(() => {
// trigger route refresh on navigate when checkin/checkout
if (isFocused && myRoute.params?.isChecked) {
const updateRouteWithCheckInOut = () => {
setIsLoading(true);
const newRoute = route;
for (let i = 0; i < newRoute.visitas.length; i++) {
const { sub_id, check_in_out } = myRoute.params;
if (newRoute.visitas[i].sub_id === sub_id) {
newRoute.visitas[i].realizada = true;
newRoute.visitas[i].check_in_out = check_in_out;
}
}
debugger;
setRoute(newRoute);
};
updateRouteWithCheckInOut();
}
}, [isFocused]);
/** ... */
}
您正在更新 for 循环中 visitas 数组的一些属性。
问题是你只是改变了一些 属性 并用相同的对象更新你的路线。如果您在 for 循环之后检查 route === newRoute,您会发现它的计算结果为真。因为它们是同一个对象。当您使用相同的对象更新路线时,React 不会重新渲染您的组件。
你应该像这样更新你的路线:
setRoute(...newRoute)
我使用 react-navigation/native
中的 useIsFocused()
函数作为 useEffect
的依赖来监听屏幕焦点,所以当我返回时它进入 if
isFocused
和 myRoute.params.isChecked
来执行函数。
但它不会更新 setRoute(newRoute);
和 setIsLoading(false)
上的路由状态。函数内的 setIsLoading(true)
被调用,但 useEffect 路由内的那个没有被调用,因为它从不调用路由更新。因此,屏幕一直在无限加载。
为什么它不更新 isLoading
和 route
状态?
import React, { useEffect, useState } from 'react';
import { useFocusEffect, useIsFocused } from '@react-navigation/native';
const MyRoute = ({ navigation, route: myRoute }) => {
const [route, setRoute] = useState({});
const [isLoading, setIsLoading] = useState(true);
const isFocused = useIsFocused();
/** ... */
useEffect(() => {
console.log('route call')
if (Object.keys(route).length) {
setIsLoading(false);
}
}, [route]);
useEffect(() => {
console.log(isLoading);
}, [isLoading]);
useEffect(() => {
// trigger route refresh on navigate when checkin/checkout
if (isFocused && myRoute.params?.isChecked) {
const updateRouteWithCheckInOut = () => {
setIsLoading(true);
const newRoute = route;
for (let i = 0; i < newRoute.visitas.length; i++) {
const { sub_id, check_in_out } = myRoute.params;
if (newRoute.visitas[i].sub_id === sub_id) {
newRoute.visitas[i].realizada = true;
newRoute.visitas[i].check_in_out = check_in_out;
}
}
debugger;
setRoute(newRoute);
};
updateRouteWithCheckInOut();
}
}, [isFocused]);
/** ... */
}
您正在更新 for 循环中 visitas 数组的一些属性。 问题是你只是改变了一些 属性 并用相同的对象更新你的路线。如果您在 for 循环之后检查 route === newRoute,您会发现它的计算结果为真。因为它们是同一个对象。当您使用相同的对象更新路线时,React 不会重新渲染您的组件。 你应该像这样更新你的路线:
setRoute(...newRoute)