跳至主要內容
版本:6.x

導覽生命週期

在上一個章節,我們使用兩個畫面(首頁明細)的堆疊導覽工具,並學習如何使用 navigation.navigate('RouteName') 在路線之間進行導覽。

在此脈絡中,一個重要問題是:當我們離開 首頁或返回 首頁時,會發生什麼事?路線如何得知使用者離開或返回該路線?

如果您來自網頁背景而開始使用 react-navigation,可能會假設當使用者從 A 路線導覽至 B 路線時,A 會卸載(呼叫 componentWillUnmount),而在使用者返回 A 路線時,A 會再次載入。雖然這些 React 生命週期方法仍然有效,並用於 react-navigation 中,但其用法與網頁不同。這是由行動導覽更複雜的需求驅動的。

範例場景

考慮一個具有 A 和 B 兩個畫面的堆疊導覽工具。在導航至 A 後,它的 componentDidMount 會被呼叫。在推進 B 之後,它的 componentDidMount 也會被呼叫,但 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 導航中運作,讓我們來回答一開始提出的問題:「我們如何得知使用者離開(模糊)它或返回到這個(焦點)畫面?」

React 導航會發出事件到訂閱這些事件的畫面元件。我們可以監聽 focusblur 事件,以分別得知畫面何時進入焦點或離開焦點。

範例

function Profile({ navigation }) {
React.useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
// Screen was focused
// Do something
});

return unsubscribe;
}, [navigation]);

return <ProfileContent />;
}

參閱導航事件,以取得關於可用事件和 API 使用的更多詳情。

我們可以使用 useFocusEffect hook 來執行附帶效應,而非手動加入事件監聽。它就像 React 的 useEffect hook,但它與導航生命週期有關。

範例

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 hook,它會傳回一個布林值表示畫面是否取得焦點。

摘要

  • 儘管 React 的生命週期方法仍然有效,但 React 導航新增了更多你可以透過 navigation 屬性訂閱的事件。
  • 你也可以使用 useFocusEffectuseIsFocused hooks。