Jo *_* Ko 8 javascript ios reactjs react-native redux
目前,我使用React Native/Redux使用NavigationStateUtils设置了Push和Pop.但是当一个触发Push动作的按钮被多次按下时,我得到错误:should not push * route with duplicated key和*表示route.key或this.props.navKey.
可能是错误的原因是什么?我该如何使用NavigationStateUtils?为每条路线创建一个唯一的密钥?
这是我的设置 - Redux:
function mapStateToProps(state) {
return {
navigation: state.navReducer,
}
}
export default connect(
mapStateToProps,
{
pushRoute: (route) => push(route),
popRoute: () => pop(),
}
)(NavigationRoot)
Run Code Online (Sandbox Code Playgroud)
我的减速机(navReducer.js):
const initialState = {
index: 0,
key: 'root',
routes: [{
key: 'login',
title: 'Login',
component: Login,
direction: 'horizontal',
}]
}
function navigationState (state = initialState, action) {
switch(action.type) {
case PUSH_ROUTE:
if (state.routes[state.index].key === (action.route && action.route.key)) return state
return NavigationStateUtils.push(state, action.route)
case POP_ROUTE:
if (state.index === 0 || state.routes.length === 1) return state
return NavigationStateUtils.pop(state)
default:
return state
}
}
export default navigationState
Run Code Online (Sandbox Code Playgroud)
这些方法处理push和pop以及如何设置导航栏后退(弹出)按钮:
_renderScene (props) {
const { route } = props.scene
return (
<route.component _handleNavigate={this._handleNavigate.bind(this)} {...route.passProps} actions={this.props}/>
)
}
_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
}
}
renderOverlay = (sceneProps) => {
if(0 < sceneProps.scene.index)
{
return (
<NavigationHeader
{...sceneProps}
renderLeftComponent={() => {
switch(sceneProps.scene.route.title){
case 'Home':
return (
<TouchableHighlight onPress={() => this._handleBackAction()}>
<Text}>X</Text>
</TouchableHighlight>
)
}
}
}
/>
)
}
}
render() {
return (
<NavigationCardStack
direction={this.props.navigation.routes[this.props.navigation.index].direction}
navigationState={this.props.navigation}
onNavigate={this._handleNavigate.bind(this)}
renderScene={this._renderScene}
renderOverlay={this.renderOverlay}
/>
)
}
Run Code Online (Sandbox Code Playgroud)
并通过如下组件调用:
const route = {
home: {
type: 'push',
route: {
key: 'home',
title: 'Home',
component: Home,
direction: 'vertical',
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑控制台日志
编辑2继续
编辑3幻灯片菜单
像这样调试你的导航减速器:
function navigationState (state = initialState, action) {
switch(action.type) {
case PUSH_ROUTE:
console.log('action', action);
if (state.routes[state.index].key === (action.route && action.route.key)) return state
const newNavigationState = NavigationStateUtils.push(state, action.route);
console.log('newNavigationState', newNavigationState);
return newNavigationState;
case POP_ROUTE:
if (state.index === 0 || state.routes.length === 1) return state
return NavigationStateUtils.pop(state)
default:
return state
}
}
Run Code Online (Sandbox Code Playgroud)
编辑
由于这种方式NavigationStateUtils.push有效(请参阅此处),它需要一个全新的路由来推送到路由堆栈。根据您的导航流程,您无法再次使用它返回主页,您必须使用不同的功能,例如NavigationStateUtils.pop或NavigationStateUtils.reset以及其他功能(浏览该文件)。但是,您不仅限于 中的函数NavigationStateUtils,您可以在减速器中定义自己的修改,但您需要确保导航状态具有以下数据格式:
{
// `routes` needs to be an array of objects and each object
// needs to have a unique `key` property
routes: [{
key: 'anything', // must be unique in this `routes` array
...anyOtherData
}],
// `index` is required, and has to be a number that refers
// to the index of the route in the routes array that is active
index: 1,
}
Run Code Online (Sandbox Code Playgroud)
编辑
根据您在评论中的要求,每次您点击抽屉项目时,都需要重置您的导航路线堆栈,以该路线为起点,然后您可以开始推送和弹出。
function navigationState (state = initialState, action) {
switch(action.type) {
case PUSH_ROUTE:
if (state.routes[state.index].key === (action.route && action.route.key)) return state
return NavigationStateUtils.push(state, action.route)
case POP_ROUTE:
if (state.index === 0 || state.routes.length === 1) return state
return NavigationStateUtils.pop(state)
case DRAWER_ITEM_PRESS:
// `action.route` is simply the route object of the drawer item you pressed
return NavigationStateUtils.reset(state, [action.route], 0);
default:
return state;
}
}
Run Code Online (Sandbox Code Playgroud)
另一方面,我认为根据您的要求,尝试使用可能是一个好主意,react-native-router-flux因为您将能够定义您的路由、子路由、与react-native-drawerRedux集成和集成。
| 归档时间: |
|
| 查看次数: |
750 次 |
| 最近记录: |