我想将Redux用于React Native。目前我没有设置数据管理,因此index.ios.js具有以下内容:
renderScene(route, navigator){
this._navigator = navigator
return (
<route.component navigator={navigator} {...route.passProps}/>
)
}
<Navigator
configureScene={this.configureScene}
initialRoute={{name: 'Login', component: Login}}
renderScene={(route, navigator) => this.renderScene(route, navigator)}
style={styles.container}
navigationBar={
<Navigator.NavigationBar
style={styles.navBar}
routeMapper={NavigationBarRouteMapper}
/>
}
/>
我打算切换到Redux。使用我当前的设置,不使用任何框架,只有例外是react-router,使用Redux导航的最佳方式是什么?使用存储,缩减器和操作的示例将非常有用。
答案 0 :(得分:5)
编辑:现在应该使用react-navigation而不是NavigationExperimental。
-
我建议您使用NavigationExperimental而不是Navigator。最后一个是折旧的。 RN文档中有一个例子right here。它使用简单的减速器来管理您的导航状态。但是你也可以使用Redux处理这个状态,因为它是相同的逻辑。
这是我使用Redux和NavigationExperimental的标签设置:
navigator.js(注意:CardStack中的renderOverlay道具将在0.32中重命名为renderHeader)
import React from 'react';
import { NavigationExperimental } from 'react-native';
import { connect } from 'react-redux';
import { pop, push, selectTab } from './actions';
const {
CardStack: NavigationCardStack,
} = NavigationExperimental;
class Navigator extends React.Component {
constructor(props) {
super(props);
this._renderHeader = this._renderHeader.bind(this);
this._renderScene = this._renderScene.bind(this);
}
_renderHeader(sceneProps) {
return (
<MyHeader
{...sceneProps}
navigate={this.props.navigate}
/>
);
}
_renderScene(sceneProps) {
return (
<MyScene
{...sceneProps}
navigate={this.props.navigate}
/>
);
}
render() {
const { appNavigationState: { scenes, tabKey, tabs } } = this.props;
return (
<View style={{ flex: 1 }}>
<NavigationCardStack
key={`stack_${tabKey}`}
navigationState={scenes}
renderOverlay={this._renderHeader}
renderScene={this._renderScene}
/>
<Tabs
navigationState={tabs}
navigate={this.props.navigate}
/>
</View>
);
}
}
const getCurrentNavigation = (navigation) => {
const tabs = navigation.tabs;
const tabKey = tabs.routes[tabs.index].key;
const scenes = navigation[tabKey];
return {
scenes,
tabKey,
tabs,
};
};
const mapStateToProps = (state) => {
return {
appNavigationState: getCurrentNavigation(state.navigation),
};
};
const mapDispatchToProps = (dispatch) => {
return {
navigate: (action) => {
if (action.type === 'pop') {
dispatch(pop());
} else if (action.type === 'push' && action.route) {
dispatch(push(action.route));
} else if (action.type === 'tab' && action.tabKey) {
dispatch(selectTab(action.tabKey));
}
}
};
};
export default connect(
mapStateToProps,
mapDispatchToProps,
)(Navigator);
actions.js
export function pop() {
return ({
type: 'POP_ROUTE',
});
}
export function push(route) {
return ({
type: 'PUSH_ROUTE',
route,
});
}
export function selectTab(tabKey) {
return ({
type: 'SELECT_TAB',
tabKey,
});
}
reducer.js(注意:我在这里使用不可变,但是你可以使用适合你的任何东西)
import { NavigationExperimental } from 'react-native';
import { Record } from 'immutable';
const {
StateUtils: NavigationStateUtils,
} = NavigationExperimental;
export const InitialState = Record({
// Tabs
tabs: {
index: 0,
routes: [
{ key: 'tab1' },
{ key: 'tab2' },
{ key: 'tab3' },
],
},
// Scenes
tab1: {
index: 0,
routes: [{ key: 'tab1' }],
},
tab2: {
index: 0,
routes: [{ key: 'tab2' }],
},
tab3: {
index: 0,
routes: [{ key: 'tab3' }],
},
});
const initialState = new InitialState();
export default function navigation(state = initialState, action) {
switch (action.type) {
case 'POP_ROUTE': {
const tabs = state.get('tabs');
const tabKey = tabs.routes[tabs.index].key;
const scenes = state.get(tabKey);
const nextScenes = NavigationStateUtils.pop(scenes);
if (scenes !== nextScenes) {
return state.set(tabKey, nextScenes);
}
return state;
}
case 'PUSH_ROUTE': {
const route = action.route;
const tabs = state.get('tabs');
const tabKey = tabs.routes[tabs.index].key;
const scenes = state.get(tabKey);
const nextScenes = NavigationStateUtils.push(scenes, route);
if (scenes !== nextScenes) {
return state.set(tabKey, nextScenes);
}
return state;
}
case 'SELECT_TAB': {
const tabKey = action.tabKey;
const tabs = state.get('tabs');
const nextTabs = NavigationStateUtils.jumpTo(tabs, tabKey);
if (nextTabs !== tabs) {
return state.set('tabs', nextTabs);
}
return state;
}
default:
return state;
}
}
最后,在 MyScene.js 组件中,您可以通过测试当前路径(例如使用开关)来处理要显示的组件。 通过在组件中传递导航功能,您可以管理您的场景(即:this.props.navigate({type:&#39; push&#39;,route:{key:&#39} ;搜索&#39;}}))。
请注意,您可以按照自己的意愿处理自己的状态和行为。理解的主要思想是如何减少状态,无论你是否使用redux。
答案 1 :(得分:2)
我建议您将react-navigation用于原生和网络环境,replace NavigationExperimental只需查看以下example。
只需在您的应用中定义导航。
import {
TabNavigator,
} from 'react-navigation';
const BasicApp = TabNavigator({
Main: {screen: MainScreen},
Setup: {screen: SetupScreen},
});
...并导航
class MainScreen extends React.Component {
static navigationOptions = {
label: 'Home',
};
render() {
const { navigate } = this.props.navigation;
return (
<Button
title="Go to Setup Tab"
onPress={() => navigate('Setup')}
/>
);
}
}
并执行以下操作以添加redux,只需定义您的reducer ...
const AppNavigator = StackNavigator(AppRouteConfigs);
const appReducer = combineReducers({
nav: (state, action) => (
AppNavigator.router.getStateForAction(action, state)
)
});
...并使用addNavigationHelpers
<AppNavigator navigation={addNavigationHelpers({
dispatch: this.props.dispatch,
state: this.props.nav,
})} />