问题
My navigation reducer set up as such:
const {
StateUtils: NavigationStateUtils
} = NavigationExperimental
const initialState = {
index: 0,
key: 'root',
routes: [{
key: 'login',
title: 'Login',
component: Login
}]
}
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
}
}
Then my button component triggers the action and navigates like so:
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
}
}
_navigate(route){
this.props._handleNavigate(route)
}
render(){
const route = {
type: 'push',
route: {
key: this.props.navKey,
title: this.props.pageName,
component: this.props.componentName
}
}
return(
<TouchableHighlight onPress={() => this._navigate(route)}>
<Text style={styles}>{pr.pageName}</Text>
</TouchableHighlight>
)
How should I go about resolving the issue with NavigationStateUtils and in the reducer format that I provided?
Thank you
回答1:
I think this happens when you try to push your 'login' route again on press of TouchableHighlight
. Can you check if your route key (this.props.navKey
) is 'login'.
So the answer is to not redirect to the same navigation route, instead use state to manage rendering.
Also, if you are just beginning, check how you can make your react components be pure functions and not classes (egghead.io has a great tutorial on using connect from react-redux).
EDIT:
So after a lot of back and forth communication with you, I think I get what you are trying to achieve: you are trying to get the "tabbed behavior" with NavigationExperimental
that is not built to do what you need out of the box. As I said, you need to rephrase your question a lot to match what you are trying to accomplish.
So, what you are trying to do is legit, but default "card stack" behavior that is taught in various tutorials is made to not allow you to do what you are trying to do for a reason: say you switch between 'login' and 'register' screens 4 times, and then press hardware back button: what is your expected behavior? Mine wouldn't be to go back and forth between 'login' and 'register' 4 times, but only once, like so: 'login' -> back -> 'register' -> back you're out of your app.
Reason I pose this question is because your answer will dictate how you write your own reducer for this behavior, because you will have to write your own reducer for your action, so besides push
and pop
, you will have, say, tabSwitch
action, that will check if your scene is already pushed onto stack and pull it to the top of the stack, if you want the behavior I describe in the previous paragraph.
来源:https://stackoverflow.com/questions/39118160/why-receiving-error-should-be-push-route-with-duplicated-key-with-regact-nativ