在前面我们学习了如何在屏幕之间导航,重要的问题是:当我们导航离开Home时,或者当我们返回Home时,会发生什么?一个路由如何发现一个用户是离开它还是回到它?
如果你要从一个web后台进行响应式导航,你可以假设当用户从路由a导航到路由B时,a会卸载(它的组件willunmount被调用),当用户返回时,a会再次加载。虽然这些React生命周期方法仍然有效,并且在React导航中使用,但它们的用法与web不同。这是由更复杂的移动导航需求驱动的。
示例场景
一个带有屏幕A和B的本机堆栈导航器。在导航到A之后,它的
componentDidMount
被调用。当push B时,B的componentDidMount
也被调用,但是A仍然挂载在堆栈上,A的componentWillUnmount
因此没有被调用。
当从B返回到A时,B的
componentWillUnmount
被调用,但是A的componentDidMount
并不会被调用,因为A一直被挂载。
function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="First">
{() => (
<SettingsStack.Navigator>
<SettingsStack.Screen
name="Settings"
component={SettingsScreen}
/>
<SettingsStack.Screen name="Profile" component={ProfileScreen} />
</SettingsStack.Navigator>
)}
</Tab.Screen>
<Tab.Screen name="Second">
{() => (
<HomeStack.Navigator>
<HomeStack.Screen name="Home" component={HomeScreen} />
<HomeStack.Screen name="Details" component={DetailsScreen} />
</HomeStack.Navigator>
)}
</Tab.Screen>
</Tab.Navigator>
</NavigationContainer>
);
}
我们从HomeScreen
开始,然后导航到DetailsScreen
。然后我们使用标签栏切换到SettingsScreen
,并导航到ProfileScreen
。在这一系列操作完成之后,所有4个屏幕都被挂载!如果你使用标签栏切换回HomeStack
,你会注意到你会看到一个DetailsScreen
- HomeStack
的导航状态被保留了!
React导航生命周期事件
现在我们已经理解了React生命周期方法在React Navigation中的工作方式,让我们来回答我们在开始时提出的问题:“我们如何发现用户是离开(blur)它还是回到它(focus)?”
React Navigation向订阅它们的屏幕组件发出事件。我们可以通过倾听
focus
和blur
事件来分别了解屏幕何时聚焦或失焦。
function Profile({ navigation }) {
React.useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
// Screen was focused
// Do something
});
return unsubscribe;
}, [navigation]);
return <ProfileContent />;
}
我们可以使用useFocusEffect
钩子来执行,而不是手动添加事件监听器。它就像React的useEffect
钩子,但它与导航生命周期紧密相连
import { useFocusEffect } from '@react-navigation/native';
function Profile() {
useFocusEffect(
React.useCallback(() => {
// Do something when the screen is focused
return () => {
// Do something when the screen is unfocused
// Useful for cleanup functions
};
}, [])
);
return <ProfileContent />;
}
如果你想根据屏幕是否聚焦来呈现不同的东西,你可以使用
useIsFocused
钩子,它返回一个布尔值,指示屏幕是否聚焦。
网友评论