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

切換畫面

在前一個單元 "你好,React Navigation",我們定義了一個具有兩個路由的堆疊導覽工具(HomeDetails),但我們尚未瞭解如何讓使用者從 Home 導覽至 Details(儘管我們已學會如何變更我們程式碼中的初始路由,強迫使用者複製我們的存放庫並變更我們程式碼中的路由才能看到另一個畫面,可以這麼說,堪稱是最糟糕的使用者體驗之一)。

如果這是網路瀏覽器,我們可以撰寫類似以下的程式碼

<a href="details.html">Go to Details</a>

撰寫此程式碼的另一種方式

<a
onClick={() => {
window.location.href = 'details.html';
}}
>
Go to Details
</a>

我們將執行類似後者的方式,但不會使用 window.location 全域變數,而是使用傳遞給我們的畫面元件的 navigation prop。

import * as React from 'react';
import { Button, View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}

// ... other code from the previous section

我們分段說明

  • navigation - navigation prop 會傳遞至原生堆疊導覽工具中每一個畫面元件定義)(稍後會在 "深入探討 navigation prop" 中提供進一步說明)。
  • navigate('Details') - 我們以想要移動使用者的路由名稱來呼叫 navigate 函式(在 navigation 屬性中,命名好難!)。
注意

如果我們以我們在瀏覽器中沒有定義的路由名稱來呼叫 navigation.navigate,這個動作會在開發版本中印出一个錯誤,而且在生產版本中不會發生任何事。换句话说,我们只能导航到在我们的导航器上已定义的路由,我们不能导航到任意的组件。

因此我们現在有一個具有兩個路由的堆疊:1)Home 路由 2)Details 路由。如果我們再次從 Details 畫面導航到 Details 路由會怎麼樣呢?

function DetailsScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Button
title="Go to Details... again"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}

如果您執行此程式碼,您會注意到當您點選「再次前往詳細資料...」時它沒有任何反應!這是因為我們已經在「詳細資料」路由中了。navigate 函式大概的意思是「前往這個畫面」,如果你已經在這個畫面中,那麼它不動作是很合理的。

讓我們假設我們實際上想要新增另一個「詳細資料」畫面。在您傳遞一些唯獨的資料到每一個路由的情況下(我們之後在討論params 時會更深入),這是相當常見的情況。要這樣做的話,我們可以將 navigate 變更為 push。這樣做可以讓我們表達想要新增另一個路由的意圖,而不論現有的導航歷程為何。

<Button
title="Go to Details... again"
onPress={() => navigation.push('Details')}
/>

每次呼叫 push 函式時,我們會在導航堆疊中新增一個路由。當您呼叫 navigate 函式時,它會先嘗試尋找具有那個名稱的現有路由,然後才會在堆疊中還沒有路由時新增一個新路由。

返回

當可以從活動畫面返回時,原生堆疊導航器所提供的標頭會自動包含一個返回按鈕(如果導航堆疊中只有一個畫面,那麼沒有什麼可以返回的,所以不會有返回按鈕)。

有時您會想要能夠以程式的方式觸發此行為,針對此目的您可以使用 navigation.goBack();

function DetailsScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Button
title="Go to Details... again"
onPress={() => navigation.push('Details')}
/>
<Button title="Go to Home" onPress={() => navigation.navigate('Home')} />
<Button title="Go back" onPress={() => navigation.goBack()} />
</View>
);
}
注意

在 Android 上,React 導航會連接到硬體返回按鈕,並在使用者按下時為你執行 `goBack()` 函數,因此其行為會符合使用者的預期。

另一項常見需求是能夠返回多個畫面 -- 例如,如果你的堆疊中有數個畫面且想要關閉所有畫面以返回第一個畫面。在此情況下,我們知道我們想要返回「首頁」,因此可以使用 `navigate('Home')`(不是 `push`!請試用並查看差異)。另一種替代方式是 `navigation.popToTop()`, 其會返回堆疊中的第一個畫面。

function DetailsScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Button
title="Go to Details... again"
onPress={() => navigation.push('Details')}
/>
<Button title="Go to Home" onPress={() => navigation.navigate('Home')} />
<Button title="Go back" onPress={() => navigation.goBack()} />
<Button
title="Go back to first screen in stack"
onPress={() => navigation.popToTop()}
/>
</View>
);
}

摘要

  • navigation.navigate('RouteName') 會將新路徑推進原生堆疊導航器(如果不在堆疊中),否則則會跳至該畫面。
  • 我們可以像這樣,重複多次呼叫 `navigation.push('RouteName')`,並將繼續推動路徑。
  • 標題列會自動顯示返回按鈕,但你可以透過呼叫 `navigation.goBack()`,以編程方式返回。在 Android 上,硬體返回按鈕的運作方式會符合預期。
  • 你可以使用 `navigation.navigate('RouteName')` 返回至堆疊中現有的畫面,並可以使用 `navigation.popToTop()` 返回至堆疊中的第一個畫面。
  • navigation prop 可供所有畫面元件使用(在路徑設定中定義為畫面的元件,並由 React 導航作為路徑加以呈現)。