¿Cómo crear una key única para NavigationStateUtils utilizando push route en React Native / Redux?

Actualmente tengo Push y Pop configurado usando NavigationStateUtils usando React Native / Redux. Pero cuando se presiona un button que activa la acción Push más de una vez, aparece el error: should not push * route with duplicated key y * que representa route.key o this.props.navKey .

¿Cuál puede ser la causa del error? ¿Cómo debo crear una key única para cada ruta individual mediante NavigationStateUtils ?

Esta es mi configuration – Redux:

 function mapStateToProps(state) { return { navigation: state.navReducer, } } export default connect( mapStateToProps, { pushRoute: (route) => push(route), popRoute: () => pop(), } )(NavigationRoot) 

Mi networkinguctor ( 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 

Y estos methods manejan push and pop y cómo se configura el button de retroceso (pop) de la barra de navigation:

  _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} /> ) } 

Y llamados por componentes así:

 const route = { home: { type: 'push', route: { key: 'home', title: 'Home', component: Home, direction: 'vertical', } } } 

EDITAR el logging de la console

introduzca la descripción de la imagen aquí introduzca la descripción de la imagen aquí

EDIT 2 Continuación

introduzca la descripción de la imagen aquí

EDIT 3 Menú diapositiva

introduzca la descripción de la imagen aquí

Depura tu networkinguctor de navigation de esta manera:

 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 } } 

EDITAR

Debido a la forma en que NavigationStateUtils.push funciona (ver aquí ), se requiere una ruta completamente nueva para empujar a la stack de routes. Según su flujo de navigation, no puede usarlo nuevamente para volver a casa, debe usar una function diferente como NavigationStateUtils.pop o NavigationStateUtils.reset y otros también (explore ese file). Sin embargo, no está limitado a las funciones en NavigationStateUtils , puede definir su propia modificación en el networkinguctor, pero debe asegurarse de que el estado de navigation tenga este formatting de datos:

 { // `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 requinetworking, and has to be a number that refers // to the index of the route in the routes array that is active index: 1, } 

EDITAR

Según sus requisitos en sus comentarios, cada vez que golpea un elemento de cajón, debe restablecer su stack de ruta de navigation teniendo esa ruta como punto de inicio, entonces puede comenzar a empujar y hacer estallar.

 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; } } 

Como otra nota al margen, veo que en function de sus requisitos, probablemente sea una buena idea intentar usar el react-native-router-flux porque podrá definir sus routes , sub-routes , integrarse con react-native-drawer e integrar con Redux .