使用 React-Native 和 Redux 在 Actions 中访问导航器

Accessing navigator in Actions with React-Native and Redux

使用 React-Native (0.19) 和 Redux,我可以像这样在 React Components 中从一个场景导航到另一个场景:

this.props.navigator.push({
 title: "Registrations",
 component: RegistrationContainer
});

此外,我希望能够从应用程序中的任何位置将组件推送到导航器(减速器 and/or 操作)。

示例流程:

  1. 用户填写表单并按下提交
  2. 我们将表单数据分派给一个动作
  3. 该操作设置已开始通过网络发送数据的状态
  4. 动作获取数据
  5. 完成后,操作会发出提交已结束的消息
  6. 操作导航到最近创建的新数据

我在方法中遇到的问题:

我觉得我遗漏了一些关于如何在不作为参数发送的情况下从操作访问 Navigator 的稍微简单的内容。

也许你可以在一个action中传递关于title和component的信息,然后带有navigator的component可以用state的信息推送到正确的场景。

在我看来,使用 Redux 处理导航的最佳方式是使用 react-native-router-flux,因为它可以将所有导航逻辑委托给 Redux:

  • 可以从reducer更改路由;

  • 您可以将路由器连接到商店并发送自己的操作,通知商店有关路由更改的信息(BEFORE_ROUTEAFTER_ROUTEAFTER_POPBEFORE_POP, AFTER_DISMISS, BEFORE_DISMISS);


一个例子

这是一个示例,说明您可以如何轻松地将当前聚焦的路由保存在商店中并在组件中处理它(这将意识到聚焦):

1。将 <Route> 连接到 Redux
<Route> 连接到 Redux 很容易,而不是:

<Route name="register" component={RegisterScreen} title="Register" />

你可以写:

<Route name="register" component={connect(selectFnForRegister)(RegisterScreen)} title="Register" />

您也可以像往常一样简单地将组件本身连接到它自己的文件中。


2。将 <Router> 连接到 Redux
如果您需要通知 Redux 导航状态(即当您弹出路由时),只需使用连接的组件覆盖 react-native-router-flux 中包含的 <Router> 组件:

import ReactNativeRouter, { Actions, Router } from 'react-native-router-flux'
const Router = connect()(ReactNativeRouter.Router) 

现在,当您使用 <Router> 时,它将连接到商店并触发以下操作:

  • Actions.BEFORE_ROUTE
  • Actions.AFTER_ROUTE
  • Actions.AFTER_POP
  • Actions.BEFORE_POP
  • Actions.AFTER_DISMISS
  • Actions.BEFORE_DISMISS

看一下 this 的例子。


3。在你的减速器中捕捉感兴趣的动作
对于这个例子,我有一个 global 减速器(我在其中保存我所有应用程序所需的信息),我在其中设置了 currentRoute:

case Actions.AFTER_ROUTE:
case Actions.AFTER_POP:
  return state.set('currentRoute', action.name)

现在 reducer 将捕获每个路由更改并使用当前聚焦的路由更新 global.currentRoute
您还可以从这里做许多其他有趣的事情,比如将导航本身的历史记录保存在一个数组中!


4.在 focus
上更新您的组件 我在名为 payment 的路线组件的 componentDidUpdate 上执行此操作。 如果 global.currentRoutepayment 并且之前的 global.currentRoute 不同,那么组件刚刚被聚焦。

  componentDidUpdate(prevProps) {
    const prevRoute = prevProps.global.currentRoute
    const currentRoute = this.props.global.currentRoute
    if (currentRoute === 'payment' && prevRoute !== currentRoute) {
      this.props.actions.doSomething()
    }
  }

P.S.: 记得检查currentRoute === 'payment',否则你会在每次路由改变时启动doSomething()!


此外,take a look a the README.md 用于学习有关与 Redux 集成的其他内容。
希望对你有帮助,Redux 万岁!