React Navigation 5.x第八章 導航器的生命週期

在之前的章節中,我們學會了使用stack導航器,其有兩個頁面(Home和Details),並且知道如何使用navigation.navigate(‘RouteName’)在兩個路由之間跳轉。

在這篇文章中,我們主要了解當我們離開Home頁面的時候都發生了什麼,以及當我們返回到這個這個的時候其又發生了什麼?路由是如何知道用戶離開或者返回到這個頁面的。

如果你之前從事過web相關工作,然後過來學習React Navigation,你就會發現當用戶從路由A跳轉到路由B的時候,A將會被卸載(componentWillUnmount方法會被調用)當用戶從其他頁面返回A頁面的時候,A頁面又會被重新加載。React 的生命週期方法在React Navigation中仍然有效,之所以用法與web不盡相同是因爲移動端導航更爲複雜。

案例場景

假設有一個stack導航器,其有A、B兩個頁面。當跳轉到A頁面的時候,它的componentDidMount將會被調用。當跳轉到B頁面的時候,B頁面的compouentDidMount也會被調用,但是A頁面依然在堆棧中保持被加載的狀態,因此其componentWillUnmount方法也沒有被調用。

當我們從B頁面返回到A頁面的時候,B頁面的compouentWillUnmount將會被調用,但是A頁面的componentDidMount不會被調用,因爲其沒有被卸載,在整個過程中一直保持被加載的狀態。

在其他類型的導航器中也是同樣的結果,假設有一個tab導航器,其有兩個tabs,每個tab就是一個stack導航器。

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頁面,然後使用標籤欄從SettingScreen 跳轉到ProfileScreen。在這一系列操作做完後,所有的四個頁面都已經被加載過了,如果你使用標籤欄返回到HomeScreen,你會注意到你將到DetailsScreen頁面----HomeStack的導航狀態已經被保存

React Navigation生命週期事件

我們知道了在React Navigation中React 生命週期方法如何工作,現在就來回答一下最開始的問題:我們如何知道用戶離開或者返回到當前頁面呢?

React Navigation將事件發送到訂閱他們的頁面組件中,我們可以通過focus和blur方法監聽用戶離開返回事件。

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

    return unsubscribe;
  }, [navigation]);

  return <ProfileContent />;
}

導航事件中可以找到更多的API用例和可用的事件

我們沒必要手動添加監聽器,我們可以使用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 掛鉤,這個會返回一個布爾值,用來指示該頁面是否獲得了焦點。

總結

  • React 的生命週期方法仍然可用,除此之外React Navigation又增加了更多的事件,你可以通過navigation屬性來訂閱他們。
  • 你也可以使用useFocusEffect或者useIsFocused倒鉤。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章