在前面我們學習了如何在屏幕之間導航出刷,重要的問題是:當我們導航離開Home時理郑,或者當我們返回Home時告私,會發(fā)生什么?一個路由如何發(fā)現(xiàn)一個用戶是離開它還是回到它?
如果你要從一個web后臺進行響應式導航,你可以假設(shè)當用戶從路由a導航到路由B時腿时,a會卸載(它的組件willunmount被調(diào)用)况脆,當用戶返回時,a會再次加載批糟。雖然這些React生命周期方法仍然有效格了,并且在React導航中使用,但它們的用法與web不同徽鼎。這是由更復雜的移動導航需求驅(qū)動的盛末。
示例場景
一個帶有屏幕A和B的本機堆棧導航器。在導航到A之后否淤,它的
componentDidMount
被調(diào)用悄但。當push B時,B的componentDidMount
也被調(diào)用石抡,但是A仍然掛載在堆棧上檐嚣,A的componentWillUnmount
因此沒有被調(diào)用。
當從B返回到A時汁雷,B的
componentWillUnmount
被調(diào)用净嘀,但是A的componentDidMount
并不會被調(diào)用报咳,因為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
的導航狀態(tài)被保留了!
React導航生命周期事件
現(xiàn)在我們已經(jīng)理解了React生命周期方法在React Navigation中的工作方式宵膨,讓我們來回答我們在開始時提出的問題:“我們?nèi)绾伟l(fā)現(xiàn)用戶是離開(blur)它還是回到它(focus)?”
React Navigation向訂閱它們的屏幕組件發(fā)出事件架谎。我們可以通過傾聽
focus
和blur
事件來分別了解屏幕何時聚焦或失焦。
function Profile({ navigation }) {
React.useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
// Screen was focused
// Do something
});
return unsubscribe;
}, [navigation]);
return <ProfileContent />;
}
我們可以使用useFocusEffect
鉤子來執(zhí)行辟躏,而不是手動添加事件監(jiān)聽器谷扣。它就像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 />;
}
如果你想根據(jù)屏幕是否聚焦來呈現(xiàn)不同的東西捎琐,你可以使用
useIsFocused
鉤子会涎,它返回一個布爾值,指示屏幕是否聚焦瑞凑。