在使用 React Navigation 的项目中,想要集成 redux 就必须要引入 react-navigation-redux-helpers 这个库。最近整理第三方库的时候,发现这两个库的版本都比较旧了,在尝试更新的时候踩了一些坑,于是就有了这篇文章。
Navigator
升级之后,配置上唯一的不同在于 v2 版本中干掉了 createReduxBoundAddListener(Key)
方法,取而代之的是 reduxifyNavigator(Navigator, Key)
。
在 v1 版本中,我们需要把前者构造出来的 addListener
作为参数传给 AppNavigator:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import { StackNavigator, addNavigationHelpers, } from 'react-navigation' import { createReduxBoundAddListener } from 'react-navigation-redux-helpers'
const AppNavigator = StackNavigator(AppRouteConfigs) const addListener = createReduxBoundAddListener("root")
class App extends React.Component { render() { return ( <AppNavigator navigation={addNavigationHelpers({ dispatch: this.props.dispatch, state: this.props.nav, addListener, // --> 就是这里 })} /> ); } }
|
而在 v2 版本中,使用新方法可以简化上述步骤:
1 2 3 4 5 6 7 8 9
| import { createStackNavigator, } from 'react-navigation' import { reduxifyNavigator } from 'react-navigation-redux-helpers'
const AppNavigator = createStackNavigator(AppRouteConfigs) const App = reduxifyNavigator(AppNavigator, "root")
|
mapStateToProps
原来 state.nav
对应的 props
键叫 “nav”,现在改为 “state” 了:
1 2 3 4 5 6 7 8 9
| const mapStateToProps = (state) => ({ nav: state.nav })
const mapStateToProps = (state) => ({ state: state.nav, })
|
另外,之前为了处理 Android 返回按钮的问题,可能会自定义一个类包裹着上面构造出来的 AppNavigator,然后通过 react-redux 的 connect
方法把 mapStateToProps
给作用到这个自定义的类上去,比如:
1 2 3 4 5 6 7 8 9 10 11
| class ReduxNavigation extends React.Component {
render() { * return <AppNavigator navigation={navigation} />; } }
export default connect(mapStateToProps)(ReduxNavigation)
|
经测试发现,在 v2 版本里,这种操作会报 “undefined is not an object(evaluating ‘state.routes’)” 的错误,猜测可能跟 Props 的键值变化有关。把 connect
的调用提前,让它先作用到 AppNavigator 再包裹到自定义类里面即可:
1 2 3 4 5 6 7 8 9 10 11 12
| const ConnectedNavigator = connect(mapStateToProps)(AppNavigator) class ReduxNavigation extends React.Component {
render() { * return <ConnectedNavigator navigation={navigation}/>; } }
export default ReduxNavigation
|
Full Example
对于同一个 Navigator, reduxifyNavigator
如果在 connect
之后调用,会报重复定义navigation
属性的错误。所以加上前面的配置过程,完整的例子应该长这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
const AppNavigator = createStackNavigator(AppRouteConfigs)
const App = reduxifyNavigator(AppNavigator, "root") const ConnectedNavigator = connect(mapStateToProps)(App)
class ReduxNavigation extends React.Component {
render() { * return <ConnectedNavigator/> } }
export default ReduxNavigation
|
参考文章
Redux integration · React Navigation
Redux integration · React Navigation (v1)