[英]React Native + Redux: What's the best and preferred navigation?
我想將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導航的最佳方式是什么? 使用存儲,縮減器和操作的示例將非常有用。
編輯:現在應該使用react-navigation而不是NavigationExperimental。
-
我建議您使用NavigationExperimental而不是Navigator。 最后一個是折舊的。 RN文檔中有一個例子, 就在這里 。 它使用簡單的減速器來管理您的導航狀態。 但是你也可以使用Redux處理這個狀態,因為它是相同的邏輯。
這是我使用Redux和NavigationExperimental選項卡的設置:
navigator.js(注意:CardStack中的renderOverlay prop將在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:'push',route:{key:'search'}}))。
請注意,您可以根據需要處理您的州和您的行為。 理解的主要思想是如何減少狀態,無論你是否使用redux。
我建議你使用react-navigation進行原生和web環境,它將取代NavigationExperimental ,看看下面的例子 。
只需在您的應用中定義導航即可。
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
在組件中addNavigationHelpers
<AppNavigator navigation={addNavigationHelpers({
dispatch: this.props.dispatch,
state: this.props.nav,
})} />
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.