React Navigation 入门(四) - 屏幕导航 Navigation 属性详解

前端之家收集整理的这篇文章主要介绍了React Navigation 入门(四) - 屏幕导航 Navigation 属性详解前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

RN 版本:0.50
操作环境:Windows 10
React Navigation 版本:1.0.0-beta.20

文章同步自简书:http://www.jianshu.com/p/6d178490b164

之前已经说过,每个在 navigator 中注册过的页面都会接受一个 navigation 属性,它包含以下几属性

  • navigate - (helper) 连接其他页面
  • state - 页面当前的状态/路由
  • setParams - (helper) 更新路由的参数
  • goBack - (helper) 关闭当前活动页面并返回
  • dispatch - 给路由器发送指令行为

在之前的几篇文章中,我们已经接触过 navigate (用来@R_452_404@面)、state(用来获取传递的参数)和 setParams(用来改变参数),这篇文章将会对它们进行更详细的说明。

注意:navigation 属性被传递给了每一个导航相关组件并且包括导航器。不过需要注意的不同点是导航器 navigator 的 navigation 属性不会包含那些 helper 类的函数navigate,goBack 等),它只有 statedispatch 属性。如果你想要使用导航器 navigation 属性中的 navigate 函数,你必须使用 dispatch 来传递一个导航操作意图(关于 Navigation Actions 下一篇文章会讲)。

与 Redux 集成时的注意事项

注:这段文字直接翻译自官方文档,由于我还没有了解过 redux,所以看得不是太懂。有兴趣的可以看看 原文

由于许多人对 navigator 顶级 API 的理解错误,他们并不能很好地正确使用 navigation 属性与 redux 的关联。导航器 navigator 如果没有接收到 navigation 属性话它会保持自己的状态,但这个并不是你通常情况下关联 redux 时想要的特征。对于嵌套在主导航器里面的各个导航器,你总是会想把 navigation 属性传递下去。这就允许你的顶级导航器去传达并给子导航器提供状态。这个时候你只需要将顶级路由与 redux 集成,因为其他的路由都被包含在了它的里面。

在 app 中跳转其它页面调用方法。它有如下参数:

navigate(routeName,params,action)

  • routeName - 在你的 app 中已经注册过的打算跳转的目的路由名称
  • params - 传给目的路由的参数
  • action - (高级)如果屏幕是导航器,则在子路由中运行的操作。有关支持的操作的完整列表,请参阅 操作文档,暂时打算下一篇文章再介绍。
class HomeScreen extends React.Component {
  render() {
    const {navigate} = this.props.navigation;
    return (
      <View>
        <Text>This is the home screen of the app</Text>
        <Button
          // 跳转到 Profile 页面并传递参数 name
          onPress={() => navigate('Profile',{name: 'Brent'})}
          title="Go to Brent's profile"
        />
      </View>
     )
   }
}

state - 屏幕当前状态/路由

一个屏幕可以通过 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' }
}
class ProfileScreen extends React.Component {
  render() {
    const {state} = this.props.navigation;
    // state.routeName === 'Profile'
    return (
      // 获取参数 name,我们之前已经见到过这种用法
      <Text>Name: {state.params.name}</Text>
    );
  }
}

setParams - 改变路由参数

触发 setParams 方法允许页面改变路由中的参数,这对于更新头部标题及按钮很有用处。上一篇文章中我们曾经介绍过这个方法

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

goBack - 关闭当前活动页面并返回

给该方法提供一个 key,来决定要从哪个路由返回(即要关闭哪个页面)。默认情况下,会关闭调用方法的当前路由。如果目标是想要回到 anywhere 而不具体地说明要关闭哪个页面,可以调用 goBack(null)

class HomeScreen extends React.Component {
  render() {
    const {goBack} = this.props.navigation;
    return (
      <View>
        <Button
          // 关闭当前的 HomeScreen
          onPress={() => goBack()}
          title="Go back from this HomeScreen"
        />
        <Button
          // 这里测试的结果也是关闭了当前的 HomeScreen
          onPress={() => goBack(null)}
          title="Go back anywhere"
        />
        <Button
          // 关闭从 'screen-123' 到栈顶的所有路由
          onPress={() => goBack('screen-123')}
          title="Go back from screen-123"
        />
      </View>
     )
   }
}

从指定的页面返回

假设我们有四个路由 A B C D 依次入栈:

navigation.navigate(SCREEN_KEY_A);
...
navigation.navigate(SCREEN_KEY_B);
...
navigation.navigate(SCREEN_KEY_C);
...
navigation.navigate(SCREEN_KEY_D);

假如你在 screen D 并且想要返回到 screen A关闭 D,C 和 B),那么你就需要这么写:

// will go to screen A FROM screen B
navigation.goBack(SCREEN_KEY_B)

注意:这个方法里面的 key 值,并不是定义 navigator 时我们给页面自定义的 key,而是上面 state 里面的 state.key。并且我们在 D 中不能直接通过 this.props.navigation.state.key获取,因为它获取的是 D 的 key,所以我们要在 B 中获取到它,然后一级一级的传递给 D,最后调用 navigation.goBack(SCREEN_KEY_B) 来回到 A。

dispatch - 给路由发送一个行为

使用 dispatch 给路由指派任意的 navigation 行为,其它的 navigation 函数使用后台的 dispatch 来实现。记住如果你想指派 react-navigation 行为的话,你应该使用库里提供的 action creators。查看 Navigation Actions获取完整的可指派行为(具体行为会在下一篇文章进行说明)。

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
  // navigate 可以嵌套 navigate action,它会在子路由里面执行
  action: NavigationActions.navigate({ routeName: 'SubProfileRoute'})
})
this.props.navigation.dispatch(navigateAction)
@H_44_301@

猜你在找的React相关文章