基本介绍

  • react-navigation 的出现替代了Navigator、 Ex-Navigation等老一代的导航组件,react-navigation可以说是Navigator的加强版,不仅有Navigator的全部功能,另外还支持底部导航类似于与iOS中的UITabBarController,此外它也支持侧拉效果方式的导航类似于Android中的抽屉效果。

基本分类

  • StackNavigator: 类似于普通的Navigator,屏幕上方导航栏;
  • TabNavigator: 相当于iOS里面的TabBarController,屏幕下方的标签栏;
  • DrawerNavigator: 抽屉效果,侧边滑出;

重要属性

# navigation

  • 通过navigation可以完成屏幕之间的调度操作,例如打开另一个屏幕;
  • 当打开页面与导航器存在映射关系,那么当前页面 const {navigation} = this.props 会拿到 navigation属性,通过此属性又包含以下属性:
1. navigate
  • 使用进行界面之间的跳转
  • navigate(routeName,params,action)
  • routeName:要跳转的界面的路由名(在导航中注册的路由名)
  • params:要传递给下一个界面的参数
  • action:若当前界面是一个navigator的话,将运行这个sub-action
  • 基本操作
export const AppStackNavigator = StackNavigator({
    HomeScreen: {
        screen: HomeScreen
    },
    Page1: {
        screen: Page1
    })

class HomeScreen extends React.Component {
  render() {
    const {navigate} = this.props.navigation;

    return (
      <View>
        <Text>This is HomeScreen</Text>
        <Button
          onPress={() => navigate('Page1', {name: 'Devio'})}
          title="Go to Page1"
        />
      </View>
     )
   }
}
2. state
  • 获取屏幕的当前state
  • 可以通过this.props.state.params来获取通过setParams(),或navigation.navigate()传递的参数。
  • 基本操作
<Button
    title={params.mode === 'edit' ? '保存' : '编辑'}
    onPress={() =>
        setParams({mode: params.mode === 'edit' ? '' : 'edit'})}
/>
<Button
    title="Go To Page1"
    onPress={() => {
        navigation.navigate('Page1',{ name: 'Devio' });
    }}
/>
const {navigation} = this.props;
const {state, setParams} = navigation;
const {params} = state;
const showText = params.mode === 'edit' ? '正在编辑' : '编辑完成';
3. setParams
  • 改变路由的params
  • setParams: function setParams(params): 我们可以借助setParams来改变route params,比如,通过setParams来更新页面顶部的标题,返回按钮等
  • 注意navigation.setParams改变的是当前页面的Params,如果要改变其他页面的Params可以通过NavigationActions.setParams完成,下文会讲到
  • 基本操作
class ProfileScreen extends React.Component {
  render() {
    const {setParams} = this.props.navigation;
    return (
      <Button
        onPress={() => setParams({name: 'Lucy'})}
        title="Set title name to 'Lucy'"
      />
     )
   }
}
4. goBack
  • 关闭当前屏幕
  • goBack: function goBack(key):我们可以借助goBack返回到上一页或者路由栈的指定页面
  • 其中key表示你要返回到页面的页面标识如id-1517035332238-4,不是routeName。
  • 可以通过指定页面的navigation.state.key来获得页面的标识。
  • key非必传,也可传null。
  • 基本操作
export default class Page1 extends React.Component {
    render() {
        const {navigation} = this.props;
        return <View style=>
            <Text style={styles.text}>欢迎来到Page1</Text>
            <Button
                title="Go Back"
                onPress={() => {
                    navigation.goBack();
                }}
            />
        </View> 
    }
}
5. dispatch
  • 向路由发送一个action
  • dispatch: function dispatch(action):给当前界面设置action,会替换原来的跳转,回退等事件。
  • 基本操作
const resetAction = NavigationActions.reset({
	index: 0,
	actions: [
	    NavigationActions.navigate({
	        routeName: 'HomePage',
	        params:{
	            theme:theme,
	            selectedTab:selectedTab
	        },
	    })
	]
	})
navigation.dispatch(resetAction)

# navigationOptions

1. title
2. headerRight
3. 动态配置

NavigationActions

1. navigate

  • 导航到其他的页面
  • 三个参数
  • routeName:字符串,必选项,在app的router里注册的导航目的地的routeName。
  • params:对象,可选项,融合进目的地route的参数。
  • actions:对象,可选项(高级),如果screen也是一个navigator,次级action可以在子router中运行。在文档中描述的任何actions都可以作为次级action。
  • 基本操作
import { NavigationActions } from 'react-navigation'

const navigateAction = NavigationActions.navigate({
  routeName: 'Profile',
  params: {},
  action: NavigationActions.navigate({ routeName: 'SubProfileRoute'})
})
this.props.navigation.dispatch(navigateAction)

2. reset

  • 删掉所有的navigation state并且使用这个actions的结果来代替
  • 两个参数:
  • index,number,必选,navigation state中route数组中激活route的index。
  • actions,array,必选项,Navigation Actions数组,将会替代navigation state
  • 基本操作
import { NavigationActions } from 'react-navigation'

const resetAction = NavigationActions.reset({
  index: 0,
  actions: [
    NavigationActions.navigate({ routeName: 'Profile'})
  ]
})
this.props.navigation.dispatch(resetAction)
  • 使用场景:比如进入APP首页后的splash页不在使用,这时可以使用*NavigationActions.reset重置它。
  • index 参数被用来定制化当前激活的route。举个例子:使用两个routes WelcomePage和HomePage给一个基础的stack navigation设置。为了重置route到HomePage,但是在堆栈中又存放在WelcomePage之上,你可以这么做:
import { NavigationActions } from 'react-navigation'

const resetAction = NavigationActions.reset({
    index: 1,
    actions: [
        NavigationActions.navigate({ routeName: 'WelcomePage'}),
        NavigationActions.navigate({ routeName: 'HomePage'})
    ]
});
this.props.navigation.dispatch(resetAction);

3. back

  • 返回到前一个screen并且关闭当前screen.backaction creator接受一个可选的参数:
  • 参数:
  • key:这个可以和上文中讲到的goBack的key是一个概念;
  • 基本操作
import { NavigationActions } from 'react-navigation'
const backAction = NavigationActions.back();
this.props.navigation.dispatch(backAction);

4. SetParams

  • 通过SetParams我们可以修改指定页面的Params。
  • 两个参数:
  • params:对象,必选参数,将会被合并到已经存在页面的Params中。
  • key:字符串,必选参数,页面的key。
  • 基本操作 :
import { NavigationActions } from 'react-navigation'
const setParamsAction = NavigationActions.setParams({
    params: { title: 'HomePage' },
    key: 'id-1517035332238-4',
});
  • navigation中有setParams为什么还要有NavigationActions.setParams?
  • 在上文中讲到过navigation中有可能只有state与dispatch,这个时候如果要修改页面的Params,则只能通过NavigationActions.setParams
  • 另外,navigation.setParams只能修改当前页面的Params,而NavigationActions.setParams可以修改所有页面的Params;

5. Init

  • 初始化一个 state 如果 state 是 undefined;

ref

  • 有一种场景:有的时候我们需要在导航器中所定义的屏幕之外使用导航器来做页面跳转。
  • 屏幕之间的跳转是需要借助navigation来完成的;
  • 我们知道导航器中定义的屏幕可以通过const {navigation} = this.props;来获取navigation
  • 那么,如果我们在非导航器中所定义的屏幕中做屏幕跳转的关键一步,就是要想法获取navigation
  • 那么,如何才能在非导航器中所定义的屏幕中获取到这个navigation呢?
  • 基本操作:
import { NavigationActions } from 'react-navigation';

const AppNavigator = StackNavigator(SomeAppRouteConfigs);

class App extends React.Component {
  someEvent() {
    // call navigate for AppNavigator here:
    this. navigation && this. navigation.dispatch(
      NavigationActions.navigate({ routeName: someRouteName })
    );
  }
  render() {
    return (
      <AppNavigator ref={nav => { navigation = nav; }} />
    );
  }
}
  • 上述代码通过导航器的顶级节点ref属性获取到navigation,当上述代码的AppNavigator节点被渲染时,ref会被回调这是就可以获取到navigation了,需要提醒大家的是,这种用法对除StackNavigator之外的其他两种类型的导航器也是实用的哦;