當你的導航卡是指路由對象和導航流行的動作發生, 您的導航卡失去了參考的彈出操作刪除路由對象。
所以我建議寫在底部的方法。
/constants/ActionTypes.js
// navigation action types
export const NAV_PUSH_ROUTE = 'NAV_PUSH_ROUTE';
export const NAV_POP_ROUTE = 'NAV_POP_ROUTE';
// tab action types
export const TAB_SELECT = 'TAB_SELECT';
/actions/navigationActions.js
/**
* Navigation Actions
* @flow
*/
import { NAV_POP_ROUTE, NAV_PUSH_ROUTE } from '../constants/ActionTypes';
const navPush = route => {
const rtRoute = route;
if (route && route.direction === undefined) rtRoute.direction = 'horizontal';
return {
type: NAV_PUSH_ROUTE,
route: rtRoute,
};
};
const navPop =() => (
{
type: NAV_POP_ROUTE,
}
);
module.exports = {
navPush,
navPop,
};
/減速器/ navigationReducer。JS
/**
* Navigation reducer
* @flow
*/
import { NavigationExperimental } from 'react-native';
import { NAV_POP_ROUTE, NAV_PUSH_ROUTE } from '../constants/ActionTypes';
const {
StateUtils: NavigationStateUtils,
} = NavigationExperimental;
const initialState = {
index: 0,
key: 'global',
routes: [
{
key: 'feed',
title: 'Feed',
},
],
};
const navigationState = (state = initialState, action) => {
switch (action.type) {
case NAV_PUSH_ROUTE:
if (state.routes[state.index].key === (action.route && action.route.key)) {
return state;
}
const navigationNewState = NavigationStateUtils.push(state, action.route);
return {
...navigationNewState,
direction: action.route.direction,
};
case NAV_POP_ROUTE:
if (state.index === 0 || state.routes.length === 1) {
return state;
}
return NavigationStateUtils.pop(state);
default:
return state;
}
};
module.exports = navigationState;
/components/global/ECNavigator.js
/**
* Everychoose navigation compoment for example
* @flow
*/
import React, { Component, PropTypes } from 'react';
import {
NavigationExperimental,
BackAndroid,
TouchableHighlight,
PixelRatio,
StyleSheet,
Text,
View,
} from 'react-native';
import { connect } from 'react-redux';
import { navPush, navPop } from '../../../actions';
import LoginScreen from '../../views/LoginScreen';
const {
CardStack: NavigationCardStack,
} = NavigationExperimental;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
},
row: {
padding: 15,
backgroundColor: '#30b3d8',
borderBottomWidth: 1/PixelRatio.get(),
borderBottomColor: '#CDCDCD',
},
rowText: {
fontSize: 17,
},
buttonText: {
fontSize: 17,
fontWeight: '500',
},
});
const routes = {
loginScreenV: {
type: 'push',
route: {
key: 'LoginScreen',
title: 'Login screen vertical',
direction: 'vertical',
},
},
loginScreenH: {
type: 'push',
route: {
key: 'LoginScreen',
title: 'Login screen horizontal',
},
},
};
class ECNavigator extends Component {
constructor(props) {
super(props);
this._renderScene = this._renderScene.bind(this);
this._handleBackAction = this._handleBackAction.bind(this);
this._handleNavigate = this._handleNavigate.bind(this);
}
componentDidMount() {
BackAndroid.addEventListener('hardwareBackPress', this._handleBackAction);
}
componentWillUnmount() {
BackAndroid.removeEventListener('hardwareBackPress', this._handleBackAction);
}
_handleBackAction() {
if (this.props.navigation.index === 0) {
return false;
}
this.props.popRoute();
return true;
}
_handleNavigate(action) {
switch (action && action.type) {
case 'push':
this.props.pushRoute(action.route);
return true;
case 'back':
case 'pop':
return this._handleBackAction();
default:
return false;
}
}
_renderScene(props) {
const { route } = props.scene;
switch (route.key) {
case 'LoginScreen':
return <LoginScreen navGoBack={this._handleBackAction} />;
default:
return (
<View style={styles.container}>
<TouchableHighlight
style={styles.row}
underlayColor="#d0d0d0"
onPress={() => this._handleNavigate(routes.loginScreenV)}
>
<Text style={styles.buttonText}>
Go to LoginScreen (Vertical)
</Text>
</TouchableHighlight>
<TouchableHighlight
style={styles.row}
underlayColor="#d0d0d0"
onPress={() => this._handleNavigate(routes.loginScreenH)}
>
<Text style={styles.buttonText}>
Go to LoginScreen (Horizontal)
</Text>
</TouchableHighlight>
</View>
);
}
}
render() {
const { navigation } = this.props;
return (
<NavigationCardStack
style={{ flex: 1 }}
direction={navigation.direction}
onNavigateBack={this._handleBackAction}
navigationState={this.props.navigation}
onNavigate={this._handleNavigate}
renderScene={this._renderScene}
/>
);
}
}
ECNavigator.propTypes = {
navigation: PropTypes.object,
pushRoute: PropTypes.func,
popRoute: PropTypes.func,
};
const select = store => ({
navigation: store.navigation,
});
const actions = dispatch => ({
pushRoute: route => dispatch(navPush(route)),
popRoute:() => dispatch(navPop()),
});
module.exports = connect(select, actions)(ECNavigator);
/components/view/LoginScreen.js
/**
* LoginScreen compoment
* @flow
*/
import React, { PropTypes } from 'react';
import {
TouchableHighlight,
PixelRatio,
StyleSheet,
Text,
View,
} from 'react-native';
import { connect } from 'react-redux';
import { navPush, navPop } from '../../../actions';
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
},
row: {
padding: 15,
backgroundColor: '#30b3d8',
borderBottomWidth: 1/PixelRatio.get(),
borderBottomColor: '#CDCDCD',
},
rowText: {
fontSize: 17,
},
buttonText: {
fontSize: 17,
fontWeight: '500',
},
});
const LoginScreen = props => (
<View style={styles.container}>
<Text style={styles.text}>Login Screen</Text>
<TouchableHighlight
style={styles.row}
underlayColor="#d0d0d0"
onPress={props.navGoBack}
>
<Text style={styles.buttonText}>
Go back
</Text>
</TouchableHighlight>
</View>
);
module.exports = LoginScreen;
Result screen - GIF
,似乎找到和你說它的工作原理是什麼? – ajmajmajma
@ajmajmajma這對'' ,並會爲' '工作不同。例如,必須傳入不同的參數,我應該返回什麼?導致'Navigator.SceneConfigs.FloatFromBottom'等不起作用。 –
@Jo Ko這不可能直接。如果你看看NavigatorCardStack _renderScene方法。它使用傳遞給NavigatorCardStack的道具來確定方向。唯一可行的方法是根據包裝組件中的活動場景更改方向道具。 https://github.com/facebook/react-native/blob/master/Libraries/CustomComponents/NavigationExperimental/NavigationCardStack.js – while1