1. 程式人生 > >React Navigation(一)-Navigation屬性(API)

React Navigation(一)-Navigation屬性(API)

你的app每一個screen元件中都自動具有了navigation屬性:

this.props.navigation

  • navigate - 跳轉到其他screen,
  • goBack - 關閉當前screen並且回退棧
  • addListener - subscribe to updates to navigation lifecycle
  • isFocused - 如果screen獲取了焦點返回true,反之false.
  • state - 當前的狀態/路由
  • setParams - 改變路由引數
  • getParam - 獲取指定引數
  • dispatch - 向路由傳送action

    要強調的是navigation屬性並不是所有的元件裡都有,只有screen元件才自動接收該屬性(

被screen屬性宣告過的元件),例如:如果你定義了一個MyBackButton元件,並且將其在一個screen元件中作為子元件渲染,那麼就不會接收到navigation屬性。

    當前導航器是stack navigator的時候,this.props.navigation中還有其他幾個函式,部分功能與navigate 和 goBack重合,可以按照個人喜好選擇使用,具體是:

this.props.navigation

  • push - 導航到棧的新的路由
  • pop - 回退
  • popToTop - 回退到棧頂
  • replace - 替換當前路由

通用 API 

    絕大多數與navigation屬性的互動都有navigate, goBack, state, 和setParams參與。

1 navigate - 連結到其他screen

呼叫方法:

navigation.navigate({routeName, params, action, key})  或者navigation.navigate(routeName, params, action)

  • routeName - 已經註冊過的目標路由名稱
  • params - 引數
  • action - (高階選項) 如果當前screen是一個導航器,表示執行在子路由器中的行為. 更多資訊檢視 Actions Doc.
  • key - 可選的識別符,表示要導航到的路由. 如果已經存在,表示返回到這個路由。
class HomeScreen extends React.Component {
  render() {
    const { navigate } = this.props.navigation;

    return (
      <View>
        <Text>This is the home screen of the app</Text>
        <Button
          onPress={() => navigate('Profile', { name: 'Brent' })}
          title="Go to Brent's profile"
        />
      </View>
    );
  }
}

2 goBack - 關閉當前screen並回退

可以給定一個key,指定要從那個路由回退。預設會關閉呼叫的路由。如果想回退到任意介面,並且不指明要關閉什麼,就呼叫.goBack(null);當StackNavigators巢狀使用,子navigator的棧中有且只有一項,父navigator中想要回退時,null引數很有用。如果你有點懵逼也不需要擔心,api還需要完善。

class HomeScreen extends React.Component {
  render() {
    const { goBack } = this.props.navigation;
    return (
      <View>
        <Button onPress={() => goBack()} title="Go back from this HomeScreen" />
        <Button onPress={() => goBack(null)} title="Go back anywhere" />
        <Button
          onPress={() => goBack('screen-123')}
          title="Go back from screen-123"
        />
      </View>
    );
  }
}

用goBack從指定screen回退

假設有如下導航棧:

navigation.navigate(SCREEN_KEY_A);

navigation.navigate(SCREEN_KEY_B);

navigation.navigate(SCREEN_KEY_C);

navigation.navigate(SCREEN_KEY_D);

你現在在screen D,向回退到A(將D,C,B彈出),你需要提供一個key,表明從哪裡回退:

navigation.goBack(SCREEN_KEY_B)// 將從B回退到A

因為A在棧頂,你也可以選擇使用navigation.popToTop();

3 addListener - Subscribe to updates to navigation lifecycle

React Navigation向訂閱過的screen元件傳送事件:

  • willBlur - screen 將要失去焦點
  • willFocus - screen 將要獲取焦點
  • didFocus - screen 獲取了焦點(if there was a transition, the transition completed)
  • didBlur - screen 失去了焦點(if there was a transition, the transition completed)

例如

const didBlurSubscription = this.props.navigation.addListener(
  'didBlur',
  payload => {
    console.debug('didBlur', payload);
  }
);

// Remove the listener when you are done
didBlurSubscription.remove();

jsonPayload:

{
  action: { type: 'Navigation/COMPLETE_TRANSITION', key: 'StackRouterRoot' },
  context: 'id-1518521010538-2:Navigation/COMPLETE_TRANSITION_Root',
  lastState: undefined,
  state: undefined,
  type: 'didBlur',
};

4 isFocused - 查詢screen的焦點狀態

如果screen獲取焦點返回true,反之返回false

let isFocused = this.props.navigation.isFocused();

如果向直接使用withNavigationFocus,將會向元件內傳入布林型別的isFocused屬性。

5 state - screen當前的狀態/路由

screen能通過this.props.navigation.state獲取到路由,返回資訊如下:

{
  // the name of the route config in the router
  routeName: 'profile',
  //a unique identifier used to sort routes
  key: 'main0',
  //an optional object of string options for this screen
  params: { hello: 'world' }
}

通過navigate和setParams傳入screen中的引數通常這樣來獲取:

class ProfileScreen extends React.Component {
  render() {
    return <Text>Name: {this.props.navigation.state.params.name}</Text>;
  }
}

6 setParams - 改變路由引數

setParams允許screen改變路由引數,這在更新頭部按鈕和標題時很有用

class ProfileScreen extends React.Component {
  render() {
    return (
      <Button
        onPress={() => this.props.navigation.setParams({ name: 'Lucy' })}
        title="Set title name to 'Lucy'"
      />
    );
  }
}

7 getParam - 獲取特定的引數值,引數未定義時有候選項

以前獲取引數時你可能遇到過引數未定義這種可怕的情況,可以用getParams來代替

以前是這樣的:

const { name } = this.props.navigation.state.params;

如果引數未定義這種方法就失敗了。

現在是這樣的:

const name = this.props.navigation.getParam('name', 'Peter');

如果name或者param未定義,Peter就是備選項

Stack Actions

以下這些actions在任何stack navigator中都可以使用:

1 Push

與navigate相似,push方法會跳轉到棧中的新路由

navigation.push(routeName, params, action)

  • routeName - 已經註冊過的目標路由名稱
  • params - 引數
  • action - (高階選項) 子路由中的行為. 

2 Pop

跳轉到棧中上一個screen。如果才一個數字引數“n”,指明要回退多少個screen

navigation.pop(n)

3 PopToTop

回退到棧頂,並關閉其他所有screen

navigation.popToTop()

4 Replace

用給定的路由替換當前screen,可以帶引數和子action

navigation.replace(routeName, params, action)

高階 API

dispatch函式並不常用,但是如果navigate和boBack無法滿足需求時也是很好的選擇

dispatch - 向路由器傳送action

使用dispatch向路由器傳送任意navigation action。The other navigation functions use dispatch behind the scenes.

如果要dispatch一個action,記得使用庫中提供的action生成器。更多資訊檢視Navigation Action Docs

import { NavigationActions } from 'react-navigation';

const navigateAction = NavigationActions.navigate({
  routeName: 'Profile',
  params: {},

  // navigate can have a nested navigate action that will be run inside the child router
  action: NavigationActions.navigate({ routeName: 'SubProfileRoute' }),
});
this.props.navigation.dispatch(navigateAction);