返回导航器内的屏幕时状态不会更新
State does not update when returning to screen inside navigator
我正在尝试根据条件设置 initialRouteName。在第一个 运行 状态设置正确,我将进入预期的屏幕,但是当我从屏幕进入 back/away 并 return 进入它时,useEffect 不会 运行 再次看到之前的屏幕。
我不确定如何在导航器中正确处理这个问题。
function ProductNavigator() {
let [initialRoute, setInitialRoute] = useState<string | null>(null);
useEffect(() => {
let getProducts = async () => {
let products = await AsyncStorage.getItem('product_list');
let isSingleProduct = products.length === 1;
setInitialRoute(isSingleProduct);
};
getProducts();
});
return (
<NativeStack.Navigator
screenOptions={{ headerShown: false }}
initialRouteName={initialRoute}
>
<NativeStack.Screen
name="SingleProduct"
component={SingleProductScreen}
/>
<NativeStack.Screen
name="MultiProducts"
component={MutliProductScreen}
/>
<NativeStack.Screen
name="SomeOtherScreen"
component={SomeOtherScreen}
/>
</NativeStack.Navigator>
);
}
更新
我使用了下面答案中的建议,得到了以下结果。当我记录每个步骤时,我可以看到状态在我需要的地方结束,但导航器忽略了我设置的 initialRouteName 并显示堆栈中的第一个屏幕。
let navigation = useNavigation();
let [initialRoute, setInitialRoute] = useState<string | null>(null);
useFocusEffect(
useCallback(() => {
let getProducts = async () => {
let products = await AsyncStorage.getItem("product_list");
let route = products.length > 1 ? "MultiProducts" : "SingleProduct";
setInitialRoute(route);
};
getProducts();
}, [])
);
useEffect(() => {
let unsub = navigation.addListener('blur', () => {
setInitialRoute(null);
});
return unsub;
}, []);
return initialRoute != null ? (
<NativeStack.Navigator
screenOptions={{ headerShown: false }}
initialRouteName={initialRoute}
>
<NativeStack.Screen
name="SingleProduct"
component={SingleProductScreen}
/>
<NativeStack.Screen name="MultiProducts" component={MutliProductScreen} />
<NativeStack.Screen name="SomeOtherScreen" component={SomeOtherScreen} />
</NativeStack.Navigator>
) : (
<NativeStack.Navigator
screenOptions={{ headerShown: false }}
>
<NativeStack.Screen name="loading" component={LoadingScreen} />
</NativeStack.Navigator>
);
UseEffects 仅在首次安装屏幕时 运行。在您的情况下,当您转到另一个屏幕时屏幕不会卸载,但基本上只是停留在后台。要解决此问题,请将 useFocusEffect 与 useCallback 结合使用。每次屏幕聚焦时都会调用此 Hook。
useFocusEffect(
React.useCallback(() => {
// do the stuff you wanna do
return () => {}; // This will be called when the screen is unfocused.
// I don't think you need that but I included it anyway
}, []));
我正在尝试根据条件设置 initialRouteName。在第一个 运行 状态设置正确,我将进入预期的屏幕,但是当我从屏幕进入 back/away 并 return 进入它时,useEffect 不会 运行 再次看到之前的屏幕。
我不确定如何在导航器中正确处理这个问题。
function ProductNavigator() {
let [initialRoute, setInitialRoute] = useState<string | null>(null);
useEffect(() => {
let getProducts = async () => {
let products = await AsyncStorage.getItem('product_list');
let isSingleProduct = products.length === 1;
setInitialRoute(isSingleProduct);
};
getProducts();
});
return (
<NativeStack.Navigator
screenOptions={{ headerShown: false }}
initialRouteName={initialRoute}
>
<NativeStack.Screen
name="SingleProduct"
component={SingleProductScreen}
/>
<NativeStack.Screen
name="MultiProducts"
component={MutliProductScreen}
/>
<NativeStack.Screen
name="SomeOtherScreen"
component={SomeOtherScreen}
/>
</NativeStack.Navigator>
);
}
更新
我使用了下面答案中的建议,得到了以下结果。当我记录每个步骤时,我可以看到状态在我需要的地方结束,但导航器忽略了我设置的 initialRouteName 并显示堆栈中的第一个屏幕。
let navigation = useNavigation();
let [initialRoute, setInitialRoute] = useState<string | null>(null);
useFocusEffect(
useCallback(() => {
let getProducts = async () => {
let products = await AsyncStorage.getItem("product_list");
let route = products.length > 1 ? "MultiProducts" : "SingleProduct";
setInitialRoute(route);
};
getProducts();
}, [])
);
useEffect(() => {
let unsub = navigation.addListener('blur', () => {
setInitialRoute(null);
});
return unsub;
}, []);
return initialRoute != null ? (
<NativeStack.Navigator
screenOptions={{ headerShown: false }}
initialRouteName={initialRoute}
>
<NativeStack.Screen
name="SingleProduct"
component={SingleProductScreen}
/>
<NativeStack.Screen name="MultiProducts" component={MutliProductScreen} />
<NativeStack.Screen name="SomeOtherScreen" component={SomeOtherScreen} />
</NativeStack.Navigator>
) : (
<NativeStack.Navigator
screenOptions={{ headerShown: false }}
>
<NativeStack.Screen name="loading" component={LoadingScreen} />
</NativeStack.Navigator>
);
UseEffects 仅在首次安装屏幕时 运行。在您的情况下,当您转到另一个屏幕时屏幕不会卸载,但基本上只是停留在后台。要解决此问题,请将 useFocusEffect 与 useCallback 结合使用。每次屏幕聚焦时都会调用此 Hook。
useFocusEffect(
React.useCallback(() => {
// do the stuff you wanna do
return () => {}; // This will be called when the screen is unfocused.
// I don't think you need that but I included it anyway
}, []));