tstat

react-navigation筆記

安裝依賴

npm install react-native-gesture-handler@1.7.0 react-native-reanimated@1.12.0 react-native-screens@2.10.1 react-native-safe-area-context@3.1.7 @react-native-community/masked-view@0.1.10 @react-navigation/compat@5.2.5 
@react-navigation/native@5.7.3 @react-navigation/stack@5.9.0

在根文件頂部引入,否則應(yīng)用會崩潰

import 'react-native-gesture-handler';

將整個應(yīng)用包裝在 NavigationContainer

import 'react-native-gesture-handler';
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';

export default function App() {
  return (
    <NavigationContainer>{/* Rest of your app code */}</NavigationContainer>
  );
}

安裝 @react-navigation/stack

npm install @react-navigation/stack

createStackNavigator 是一個返回一個對象(包含2個屬性 ScreenNavigator )的函數(shù)。 Navigator 應(yīng)該包含子元素 Screen ,來定義路由配置溢陪。用 NavigationContainer 包裹 Navigator

// In App.js in a new project

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

function HomeScreen() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
    </View>
  );
}

function DetailsScreen() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Details Screen</Text>
    </View>
  );
}

const Stack = createStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator
        initialRouteName="Home"
        screenOptions={{ gestureEnabled: true }}>
        <Stack.Screen name="Home" component={HomeScreen} options={{ title: 'Overview' }}/>
        <Stack.Screen name="Details" component={DetailsScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;

配置

Screen 的必需配置屬性是 namecomponent 。在 Navigator 上配置 initialRouteName

component 屬性接受組件盏浇,不接受一個render函數(shù)。不要傳一個內(nèi)聯(lián)函數(shù)例如 component={() => <HomeScreen />} 芽狗,否則當父組件re-render時绢掰,你的組件將卸載和重載失去的所有state。

每個路由的配置可以放在 options 里面。相同的可以配在 NavigatorscreenOptions 里面滴劲。

傳遞額外的props:

  • (推薦)使用React Context攻晒,用context provider包裹navigator去傳數(shù)據(jù)到screens。
// Context lets us pass a value deep into the component tree
// without explicitly threading it through every component.
// Create a context for the current theme (with "light" as the default).
const ThemeContext = React.createContext('light');

class App extends React.Component {
  render() {
    // Use a Provider to pass the current theme to the tree below.
    // Any component can read it, no matter how deep it is.
    // In this example, we're passing "dark" as the current value.
    return (
      <ThemeContext.Provider value="dark">
        <Toolbar />
      </ThemeContext.Provider>
    );
  }
}

// A component in the middle doesn't have to
// pass the theme down explicitly anymore.
function Toolbar() {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

class ThemedButton extends React.Component {
  // Assign a contextType to read the current theme context.
  // React will find the closest theme Provider above and use its value.
  // In this example, the current theme is "dark".
  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;
  }
}

  • 用render callback而不是定義一個component prop班挖。默認情況下react-navigation底層做了優(yōu)化防止重復(fù)渲染鲁捏,但是使用render callback則會移除這些優(yōu)化。如果用render callback萧芙,需要確保Screen組件使用了 React.memoReact.PureComponent
<Stack.Screen name="Home">
  {props => <HomeScreen {...props} extraData={someData} />}
</Stack.Screen>

路由跳轉(zhuǎn)

import * as React from 'react';
import { Button, View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/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 屬性會傳遞給每個在stack navigator中定義的screen component缕碎。

  • navigation.navigate('Detail') 調(diào)用navigate方法傳入路由name,可以跳轉(zhuǎn)到對應(yīng)頁面墓毒。

  • navigation.push('Detail') 可以做到在Detail頁面打開另一個Detail頁面句喷。

  • navigation.goBack() 路由回退。

  • 回退多個頁面的方式:

    1. navigate('Home') 回退到Home頁渔期。

    2. 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>
  );
}

路由傳參

步驟:

  1. navigation.navigate('RouteName', { /* params go here */ }) ,推薦使用JSON格式的參數(shù)疯趟。
  2. 在screen組件中讀取傳入的參數(shù) route.params 拘哨。
function HomeScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
      <Button
        title="Go to Details"
        onPress={() => {
          /* 1. Navigate to the Details route with params */
          navigation.navigate('Details', {
            itemId: 86,
            otherParam: 'anything you want here',
          });
        }}
      />
    </View>
  );
}

function DetailsScreen({ route, navigation }) {
  /* 2. Get the param */
  const { itemId } = route.params;
  const { otherParam } = route.params;
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Details Screen</Text>
      <Text>itemId: {JSON.stringify(itemId)}</Text>
      <Text>otherParam: {JSON.stringify(otherParam)}</Text>
      <Button
        title="Go to Details... again"
        onPress={() => navigation.push('Details', { itemId: Math.floor(Math.random() * 100) }}
      />
      <Button title="Go to Home" onPress={() => navigation.navigate('Home')} />
      <Button title="Go back" onPress={() => navigation.goBack()} />
    </View>
  );
}

更新路由參數(shù): navigation.setParams

傳參回到上一個頁面: navigation.navigate('',params)

傳參到嵌套的路由器:

navigation.navigate('Account', {
  screen: 'Settings',
  params: { user: 'jane' },
});

配置標題欄

設(shè)置標題:(在 Screen 上設(shè)置 options

  1. options={{ title: 'My home' }}
  2. options={({ navigation, route }) => ({ title: route.params.name })} 信峻, options 函數(shù)的參數(shù)包括 navigationroute 倦青,我們只需用到 route
  3. 使用 navigation.setOptions({ title:'Updated!' }) 更新 options

修改header樣式:(在 Screen 上設(shè)置 options

  1. headerStyle :參考View的樣式寫法
  2. headerTintColor
  3. headerTitleStyle :參考Text的樣式寫法
  4. 注意:iOS上,status bar的文字和圖標是黑色的盹舞,詳見適配方案

復(fù)用常規(guī)options:

  1. Stack.Navigator 上配置屬性 screenOptions

自定義組件替換標題: headerTitle (默認是展示text的Text組件)

其他options:詳見文檔

function LogoTitle() {
  return (
    <Image
      style={{ width: 50, height: 50 }}
      source={require('@expo/snack-static/react-native-logo.png')}
    />
  );
}

function StackScreen() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Home"
        component={HomeScreen}
        options={{ headerTitle: props => <LogoTitle {...props} /> }}
      />
    </Stack.Navigator>
  );
}

header 按鈕

添加header按鈕

  1. headerRight
function StackScreen() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Home"
        component={HomeScreen}
        options={{
          // 在options里 this 不指向HomeScreen實例姨夹,不能調(diào)用setState或其他實例方法
          headerTitle: props => <LogoTitle {...props} />,
          headerRight: () => (
            <Button
              onPress={() => alert('This is a button!')}
              title="Info"
              color="#fff"
            />
          ),
        }}
      />
    </Stack.Navigator>
  );
}

header與它的screen組件交互

  1. 定義按鈕時,在screen組件內(nèi)使用 navigation.setOptions 而不是 options 屬性矾策,這樣可以獲取screen的props磷账、state、context等贾虽。
function StackScreen() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Home"
        component={HomeScreen}
        options={({ navigation, route }) => ({
          headerTitle: props => <LogoTitle {...props} />,
        })}
      />
    </Stack.Navigator>
  );
}

function HomeScreen({ navigation }) {
  const [count, setCount] = React.useState(0);

  React.useLayoutEffect(() => {
    navigation.setOptions({
      headerRight: () => (
        <Button onPress={() => setCount(c => c + 1)} title="Update count" />
      ),
    });
  }, [navigation]);

  return <Text>Count: {count}</Text>;
}

配置回退按鈕

  1. createStackNavigator 提供平臺定制的默認回退按鈕逃糟。
  2. headerBackTitle
  3. headerTruncatedBackTitle文檔
  4. headerBackImage文檔

覆蓋回退按鈕

  1. headerRight
  2. headerLeft
  3. 保留button只覆蓋 onPress 方法,可以從 @react-navigation/stack 導(dǎo)出 HeaderBackButton 組件分配給 headerLeft 選項

嵌套導(dǎo)航器(todo)

在一個導(dǎo)航器的Screen內(nèi)渲染另一個導(dǎo)航器蓬豁。

  • Stack.Navigator
    • Home ( Tab. Navigator )
      • Feed ( Screen )
      • Messages ( Screen )
    • Profile ( Screen )
    • Settings ( Screen )
function Home() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Feed" component={Feed} />
      <Tab.Screen name="Messages" component={Messages} />
    </Tab.Navigator>
  );
}

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={Home} />
        <Stack.Screen name="Profile" component={Profile} />
        <Stack.Screen name="Settings" component={Settings} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

注意:

  • 每個嵌套導(dǎo)航器保持自己的導(dǎo)航歷史
  • 每個嵌套導(dǎo)航器有自己的 options
  • 每個嵌套導(dǎo)航器有自己的參數(shù)
    • 如果需要從父Screen傳參到子Screen绰咽,可以用React Context透傳參數(shù)給children
  • 導(dǎo)航actions(比如 goBacknavigate )會被當前導(dǎo)航器處理地粪,如果處理不了則會冒泡(被父導(dǎo)航器)處理
  • 導(dǎo)航器的特定方法在嵌套導(dǎo)航器中也可用:
    • 如果需要從父導(dǎo)航器dispatch actions到嵌套的子導(dǎo)航器取募,可以使用 navigation.dispatch
// 從父導(dǎo)航器dispatch actions到嵌套的子導(dǎo)航器
navigation.dispatch(DrawerActions.toggleDrawer());

{/** Drawer的openDrawer方法可以被Stack調(diào)用(navigation.openDrawer) */}
<Drawer>
  <Stack />
  {/** ... */}
</Drawer>

{/** Drawer的openDrawer方法不可被Stack下的其他Screen調(diào)用 */}
<Stack>
  <Drawer />
  {/** ... */}
</Stack>

{/** Tab可以調(diào)用Stack的方法push和replace(navigation.push、navigation.replace) */}
<Stack>
  <Tab/>
  {/** ... */}
</Stack>

嵌套導(dǎo)航器不接收父導(dǎo)航器的事件蟆技,如需接受父導(dǎo)航器的事件玩敏,需要使用 navigation.dangerouslyGetParent() 顯式監(jiān)聽

const unsubscribe = navigation
  .dangerouslyGetParent()
  .addListener('tabPress', (e) => {
    // Do something
  });

父導(dǎo)航器的UI渲染在子導(dǎo)航器的最頂端:

  • Drawer的每一個頁面中嵌套Stack:抽屜出現(xiàn)在堆棧標題的上方
  • Stack中嵌套Drawer:抽屜顯式在標題下方
  • Stack的首頁中嵌套Tab:新頁面會覆蓋掉tab bar
  • Tab的每一個頁面中嵌套Stack:tab bar一直顯示斗忌,再按一下tab會回到stack的頂部

在嵌套導(dǎo)航器中跳轉(zhuǎn)頁面

  • Drawer.Navigator
    • Drawer.ScreenHome
    • Drawer.ScreenRoot
      • Stack.ScreenProfile
      • Stack.ScreenSettings
navigation.navigate('Root');
navigation.navigate('Root', { screen: 'Settings' });

在以前的版本中,所有配置都是靜態(tài)的旺聚,但是現(xiàn)在通過動態(tài)配置织阳,直到包含Screen的導(dǎo)航器呈現(xiàn)之前,react-navigation才知道哪些Screen可用以及在哪里可用砰粹。通常唧躲,Screen在導(dǎo)航進入之前不會渲染任何東西,因此尚未渲染的導(dǎo)航器配置不可用碱璃。這使得必須制定要導(dǎo)航到的層次結(jié)構(gòu)弄痹。這也是為什么應(yīng)該盡可能減少嵌套導(dǎo)航器以使代碼更簡單的原因。

將參數(shù)傳遞給嵌套導(dǎo)航器中Screen

// 指定params傳遞參數(shù)
navigation.navigate('Root', {
  screen: 'Settings',
  params: {
    user: 'jane'
  },
});

// 深層嵌套
navigation.navigate('Root', {
  screen: 'Settings',
  params: {
    screen: 'Sound',
    params: {
      screen: 'Media',
    },
  },
});

渲染定義在導(dǎo)航器中的初始路由

默認情況下嵌器,在嵌套導(dǎo)航器中導(dǎo)航Screen時界酒,指定的screen會被用作初始screen,并且導(dǎo)航器上的initialRoute prop會被忽略嘴秸。

如果需渲染特定的初始路由頁面,可以設(shè)置 initial: false 庇谆。

navigation.navigate('Root', {
  screen: 'Settings',
  initial: false,
});

嵌套多個stack 導(dǎo)航器

當嵌套多個Stack導(dǎo)航器時岳掐,react-navigation將自動隱藏子stack導(dǎo)航器的標題,以避免重復(fù)的標題饭耳。但是根據(jù)場景不同串述,顯示子stack導(dǎo)航器的標題,而不是隱藏父stack導(dǎo)航器的標題寞肖,可能更有用纲酗。可以設(shè)置 headerShown: false 解決該問題新蟆。完整示例 極少的情況觅赊,你需要同事顯示父stack導(dǎo)航器和子stack導(dǎo)航器的標題,可以在子導(dǎo)航器上設(shè)置 headerShown: true

function Home() {
  return (
    <NestedStack.Navigator>
      <NestedStack.Screen name="Profile" component={Profile} />
      <NestedStack.Screen name="Settings" component={Settings} />
    </NestedStack.Navigator>
  );
}

function App() {
  return (
    <NavigationContainer>
      <RootStack.Navigator>
        <RootStack.Screen
          name="Home"
          component={Home}
          options={{ headerShown: false }}
        />
        <RootStack.Screen name="EditPost" component={EditPost} />
      </RootStack.Navigator>
    </NavigationContainer>
  );
}

嵌套的最佳做法:建議將嵌套導(dǎo)航器減少到最小琼稻。嘗試通過盡可能少的嵌套來實現(xiàn)所需的行為吮螺。缺點如下

  • 會導(dǎo)致深度嵌套的視圖層級結(jié)構(gòu),從而可能導(dǎo)致低端設(shè)備出現(xiàn)內(nèi)存和性能問題
  • 嵌套相同類型的導(dǎo)航器可能會導(dǎo)致混淆的用戶體驗
  • 如果嵌套過多帕翻,導(dǎo)航到嵌套頁面鸠补,配置深層鏈接等時將很難編寫代碼

導(dǎo)航生命周期

堆棧導(dǎo)航器中包含A和B兩個screen。當導(dǎo)航到A頁面時嘀掸,A的 componentDidMount 被調(diào)用紫岩,當跳轉(zhuǎn)到B時,B的 componentDidMount 被調(diào)用睬塌,但是A在stack中保持mounted泉蝌,A的 componentWillUnmount 沒有被調(diào)用歇万。

當從B回退到A時,B的 componentWillUnmmount 被調(diào)用梨与,但是A的 componentDidMount 沒有被調(diào)用堕花,因為A一直是mounted狀態(tài)。

生命周期事件文檔

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

    return unsubscribe;
  }, [navigation]);

  return <ProfileContent />;
}
  1. 代替手動添加事件監(jiān)聽粥鞋,可以用 useFocusEffect hook去執(zhí)行副作用缘挽,類似react的 useEffect hook。
  2. 使用 useIsFocused hook:返回boolean呻粹,表示屏幕是否聚焦
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 />;
}

打開全屏modal(需要嵌套導(dǎo)航器知識)

在Navigator上設(shè)置屬性 mode="modal" 壕曼,調(diào)用 navigation.navigate 打開modal

function HomeScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text style={{ fontSize: 30 }}>This is the home screen!</Text>
      <Button
        onPress={() => navigation.navigate('MyModal')}
        title="Open Modal"
      />
    </View>
  );
}

function DetailsScreen() {
  return (
    <View>
      <Text>Details</Text>
    </View>
  );
}

function ModalScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text style={{ fontSize: 30 }}>This is a modal!</Text>
      <Button onPress={() => navigation.goBack()} title="Dismiss" />
    </View>
  );
}

const MainStack = createStackNavigator();
const RootStack = createStackNavigator();

function MainStackScreen() {
  return (
    <MainStack.Navigator>
      <MainStack.Screen name="Home" component={HomeScreen} />
      <MainStack.Screen name="Details" component={DetailsScreen} />
    </MainStack.Navigator>
  );
}

function RootStackScreen() {
  return (
    <RootStack.Navigator mode="modal">
      <RootStack.Screen
        name="Main"
        component={MainStackScreen}
        options={{ headerShown: false }}
      />
      <RootStack.Screen name="MyModal" component={ModalScreen} />
    </RootStack.Navigator>
  );
}

注意:

  • mode 可以設(shè)置為 card (默認)和 modal (iOS:從底部劃出,從頂部向下滑動以關(guān)閉等浊;安卓:無效)
  • 當調(diào)用 navigate 時腮郊,除了路由外,無需指定其他任何內(nèi)容筹燕。(react-navigation嘗試在最近的導(dǎo)航器上查找路由轧飞,然后在該位置執(zhí)行操作)

Tab Navigator(todo)

文檔

術(shù)語表

header: 屏幕頂端的矩形,包含回退按鈕和標題

Navigator :包含子元素 Screen 撒踪。NavigationContainer是一個管理導(dǎo)航樹和包含導(dǎo)航狀態(tài)的組件过咬。這個組件必須包著所有的導(dǎo)航結(jié)構(gòu)。通常我們在app的頂部(通常在App.js里)渲染這個組件制妄。

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator> // <---- This is a Navigator
        <Stack.Screen name="Home" component={HomeScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

Screen 組件:定義路由配置的組件

被配置在路由配置里的Screen組件(被 navigation.navigate 喚起的Screen)被提供了 navigation props掸绞,

const Stack = createStackNavigator();

const StackNavigator = (
  <Stack.Navigator>
    <Stack.Screen
      name="Home"
      component={HomeScreen} // <----
    />
    <Stack.Screen
      name="Details"
      component={DetailsScreen} // <----
    />
  </Stack.Navigator>
);

Navigation prop navigation prop文檔

  • dispatch
  • navigate
  • goBack
  • ...

Route proproute prop文檔

  • params
  • key
  • name

Navigation state:結(jié)構(gòu)如下,index指向當前的路由(B)

{
  key: 'StackRouterRoot',
  index: 1,
  routes: [
    { key: 'A', name: 'Home' },
    { key: 'B', name: 'Profile' },
  ]
}

Route

{
  key: 'B',
  name: 'Profile',
  params: { id: '123' }
}

兼容性層:降低升級的代碼改動成本

  • 安裝 @react-navigation/compat :
npm install @react-navigation/native @react-navigation/compat @react-navigation/stack
  • 使用 createCompatNavigatorFactory 包裹
-import { createStackNavigator } from 'react-navigation-stack';
+import { createStackNavigator } from '@react-navigation/stack';
+import { createCompatNavigatorFactory } from '@react-navigation/compat';
-const RootStack = createStackNavigator(
+const RootStack = createCompatNavigatorFactory(createStackNavigator)(
  {
    Home: { screen: HomeScreen },
    Profile: { screen: ProfileScreen },
  },
  {
    initialRouteName: 'Profile',
  }
);
  • NavigationActions 改為從 @react-navigation/compat 中導(dǎo)出
-import { NavigationActions } from 'react-navigation';
+import { NavigationActions } from '@react-navigation/compat';
  • @react-navigation/compat 導(dǎo)出的api包括:

    • Actions:
      • NavigationActions
      • StackActions
      • DrawerActions
      • SwitchActions
    • HOCs
      • withNavigation
      • withNavigationFocus
    • Navigators
      • createSwitchNavigator
    • Compatibility helpers
      • createCompatNavigatorFactory - 傳入一個使用v5的api的導(dǎo)航器耕捞,返回一個使用v4 api的 createXNavigator
      • createCompatNavigationProp - 傳入一個v5 的 navigation 對象 和route對象衔掸,返回一個v4的 navigation 對象
  • 兼容層處理了:

    • 使用v4的靜態(tài)配置api,俄日不是基于api的組件
    • 改變了navigation對象上的方法名稱去適配v4
    • 添加了對screenProps的支持(v5上被移除)
    • 導(dǎo)出了跟v4同名的action creators俺抽,例如NavigationActions敞映、StackActionsSwitchActions磷斧。
  • 兼容層沒處理:v5動態(tài)api導(dǎo)致v4靜態(tài)api不再具有某些功能

    • 不再包含navigator的props或者options驱显。意味著你要傳遞給navigator的options可能因為重大改變而不同。
    • 通過在路由配置中定義path來定義舊式深層鏈接是不支持的
    • 導(dǎo)航到導(dǎo)航器的工作原理不同瞳抓,我們無法導(dǎo)航到尚未渲染的導(dǎo)航器中的屏幕埃疫,并且參數(shù)不會合并到所有子屏幕。
    • 某些采取一系列操作的方法例如reset將不再支持孩哑。
    • 不導(dǎo)出createAppContainer栓霜,需要對容器使用v5的apiNavigationContainer
    • 如果使用的高階api例如Redux集成横蜒、自定義路由器胳蛮、actions销凑,這些不再支持,并且你需要移除Redux集成仅炊。
  • 為什么用:

    • 允許使用新api寫代碼斗幼,同時使用舊api與代碼集成
    • 建立在支持TypeScript的v5之上,舊代碼也可以利用類型檢查功能抚垄,對重構(gòu)有幫助
    • 可以在舊組件中訪問新api蜕窿,例如navigation.setOptions或者一些新的hook例如useFocusEffect

在沒用navigation props時navigate

  • 有時你需要從一個沒有navigation prop的地方觸發(fā)navigation action呆馁,比如redux middleware桐经,在這種時候,你可以從navigation容器中dispatch navigation actions浙滤。

  • 如果你想要找一種方式阴挣,從一個不需要傳navigation prop下去的組件里面navigate,可以用useNavigation纺腊。當你可以拿到navigation prop或者useNavigation時不要用這個方法畔咧,因為它的行為會有所不同,而且許多特定于屏幕的helper方法將不可用揖膜。

  • 你可以通過ref訪問根導(dǎo)航器對象誓沸,將其傳遞給RootNavigation,我們稍后將使用該RootNavigation進行導(dǎo)航次氨。

// App.js
import { NavigationContainer } from '@react-navigation/native';
import { navigationRef } from './RootNavigation';

export default function App() {
  return (
    <NavigationContainer ref={navigationRef}>{/* ... */}</NavigationContainer>
  );
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市摘投,隨后出現(xiàn)的幾起案子煮寡,更是在濱河造成了極大的恐慌,老刑警劉巖犀呼,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件幸撕,死亡現(xiàn)場離奇詭異,居然都是意外死亡外臂,警方通過查閱死者的電腦和手機坐儿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宋光,“玉大人貌矿,你說我怎么就攤上這事∽锛眩” “怎么了逛漫?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長赘艳。 經(jīng)常有香客問我酌毡,道長克握,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任枷踏,我火速辦了婚禮菩暗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘旭蠕。我一直安慰自己停团,他們只是感情好,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布下梢。 她就那樣靜靜地躺著客蹋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪孽江。 梳的紋絲不亂的頭發(fā)上讶坯,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機與錄音岗屏,去河邊找鬼辆琅。 笑死,一個胖子當著我的面吹牛这刷,可吹牛的內(nèi)容都是我干的婉烟。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼暇屋,長吁一口氣:“原來是場噩夢啊……” “哼似袁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起咐刨,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤昙衅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后定鸟,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體而涉,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年联予,在試婚紗的時候發(fā)現(xiàn)自己被綠了啼县。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡沸久,死狀恐怖季眷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情卷胯,我是刑警寧澤瘟裸,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站诵竭,受9級特大地震影響话告,放射性物質(zhì)發(fā)生泄漏兼搏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一沙郭、第九天 我趴在偏房一處隱蔽的房頂上張望佛呻。 院中可真熱鬧,春花似錦病线、人聲如沸吓著。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绑莺。三九已至,卻和暖如春惕耕,著一層夾襖步出監(jiān)牢的瞬間纺裁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工司澎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留欺缘,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓挤安,卻偏偏與公主長得像谚殊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蛤铜,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355