Redux集成
Redux集成概述
想要在redux中处理你的应用程序的
navigation状态,您可以将自己的navigation属性传递给navigator。一旦将自己的
navigation属性传递给navigator,默认的navigation属性就会被销毁。你可能需要传递你想要访问的navigation属性。通常state和dispatch的属性会被传递给navigator。你将在本教程中学习如何传递这些属性。 既然你已经销毁了默认的属性,如果你尝试调用一些你没有明确传递的东西,那么它将不起作用。 因此,如果你没有将dispatch传递给navigator,并且只传递了state,那么您将无法访问组件中的dispatch方法。state将从被分配的reducer到处理navigation状态和将成为redux的默认dispatch的dispatch。因此你将能够使用this.props.navigation.dispatch(ACTION)调度正常的redux方法。reducer将根据调度的方法更新navigation状态,新的navigation状态将会被传递给navigator。
有关Redux集成的详细信息
使用 redux ,你的应用程序的状态将由 reducer 定义。每个导航路由都有一个叫做 getStateForAction 的 reducer 。以下是在集成了 redux 的应用中如何使用 navigator 的最简单示例:
import { addNavigationHelpers } from 'react-navigation';
const AppNavigator = StackNavigator(AppRouteConfigs);
const initialState = AppNavigator.router.getStateForAction(AppNavigator.router.getActionForPathAndParams('Login'));
const navReducer = (state = initialState, action) => {
const nextState = AppNavigator.router.getStateForAction(action, state);
// Simply return the original `state` if `nextState` is null or undefined.
return nextState || state;
};
const appReducer = combineReducers({
nav: navReducer,
...
});
class App extends React.Component {
render() {
return (
<AppNavigator navigation={addNavigationHelpers({
dispatch: this.props.dispatch,
state: this.props.nav,
})} />
);
}
}
const mapStateToProps = (state) => ({
nav: state.nav
});
const AppWithNavigationState = connect(mapStateToProps)(App);
const store = createStore(appReducer);
class Root extends React.Component {
render() {
return (
<Provider store={store}>
<AppWithNavigationState />
</Provider>
);
}
}
一旦你这样做,你的 navigation 状态将会保存到你的 redux 存储中,你可以使用 redux 的调度功能来触发 navigation 的事件
请记住,当 navigator 被给予一个 navigation 属性时,它会放弃对其内部状态的控制。这意味着你现在负责管理其状态、处理深层链接Handling the Hardware Back Button in Android、等等
navigation 状态在嵌套时自动从一个 navigator 传递到另一个 navigator ,请注意:为了使子 navigator 从父 navigator 中接收状态,你应该将其定义为一个页面
把这些应用到上面的例子中,你可以定义包含了一个嵌套的 TabNavigator 的 AppNavigator 来替代之前的,如下所示:
const AppNavigator = StackNavigator({
Home: { screen: MyTabNavigator },
});
这样,只要在 AppWithNavigationState 中完成了 将 AppNavigator connect 到Redux, MyTabNavigator 将自动获得像访问 navigation 属性一样访问 navigation 状态的权限。
所有的栗子
如果你想自己尝试一下,这儿有一个使用Redux的示例应用 戳我
Mocking tests
为了使jest测试能够与你的react-navigation应用一起工作,你需要修改 package.json 中jest的预设配置信息,参阅这儿:
"jest": {
"preset": "react-native",
"transformIgnorePatterns": [
"node_modules/(?!(jest-)?react-native|react-navigation)"
]
}
Handling the Hardware Back Button in Android
使用一下的代码片段,你的导航组件将能够感知返回键的点击事件,并将正确处理与堆栈之间的交互。这在Android上非常有用。
import React from "react";
import { BackHandler } from "react-native";
import { addNavigationHelpers, NavigationActions } from "react-navigation";
const AppNavigation = TabNavigator(
{
Home: { screen: HomeScreen },
Settings: { screen: SettingScreen }
}
);
class ReduxNavigation extends React.Component {
componentDidMount() {
BackHandler.addEventListener("hardwareBackPress", this.onBackPress);
}
componentWillUnmount() {
BackHandler.removeEventListener("hardwareBackPress", this.onBackPress);
}
onBackPress = () => {
const { dispatch, nav } = this.props;
if (nav.index === 0) {
return false;
}
dispatch(NavigationActions.back());
return true;
};
render() {
const { dispatch, nav } = this.props;
const navigation = addNavigationHelpers({
dispatch,
state: nav
});
return <AppNavigation navigation={navigation} />;
}
}
