Tell us which versions you are using:
null or throws an Error of some kindWhen calling Actions.popTo on a route that is not in the navigation stack, it infinite loops (inside of the Reducer)
Additionally, I expected it to "just work" given a parent route. More context:
Actions.popTo the tabs route and it would "just work", instead it infinite loops. popTo that child routeFor non-obvious bugs, please fork this component, modify Example project to reproduce your issue and include link here.
@Jarred-Sumner I am able to reproduce the error - but it seems to be related to react-navigation. But I believe something can be done over it to avoid that. I will spare some time this week to investigate this issue. Thank you.
Alright - I believe I found the cause of the issue. When reaching the top level, the state is always the same - never finding the undefined route. That might also happen with a defined route in a different stack level.
Adjusted to verify if the current state is the same as the top level from the current router - if does, just break the loop.
I solved this by overloading the popTo in the reducer that you give to the Router.createReducer.
export const reducerCreate = (params) => {
const defaultReducer = Reducer(params, {});
return (state, action)=>{
if (action && action.type == "REACT_NATIVE_ROUTER_FLUX_POP_TO") {
// check if we can see the key in the list of items, if not, do a back.
let popCount = 0;
let success = false;
// search throught all routes in the state, starting from the top, for one that matches the route name
for (let i = state.index; i >= 0; i--) {
if (state.routes[i].routeName == action.routeName) {
// we found it!
success = true
break;
}
// how many pops do we need for this operation?
popCount++;
}
if (success) {
// if our routing stack is [1, 2, 3, 4, 5] and we're in 5 and want to go back to 1, we remove [2,3,4] so [1,5] are left, then do a nav/back for animated transition
// cut out the intermediates ([2,3,4])
if (popCount == 1) {
return defaultReducer(state, {type: "Navigation/BACK"});
}
else if (popCount > 1) {
let newState = {...state};
newState.routes = newState.routes.slice(0, newState.routes.length - popCount);
// push the current scene back on top of the stack.
newState.routes.push(state.routes[state.routes.length-1])
// have the index point to a the correct scene.
newState.index -= (popCount - 1);
// go back one step to go from 5 to 1
return defaultReducer(newState, {type: "Navigation/BACK"});
}
else {
// popCount = 0, we're already there?
LOGw.info("navigation.ts: Tried PopTo with name", action.routeName, " while already on that route. Popping once.")
return defaultReducer(state, {type: "Navigation/BACK"});
}
}
else {
// just go back one if we can't find the target?
LOGw.info("navigation.ts: Tried PopTo with name", action.routeName, " but could not find target route. Popping once.")
return defaultReducer(state, {type: "Navigation/BACK"});
}
}
return defaultReducer(state, action);
}
};
edit:
usage:
<Router createReducer={reducerCreate} ... >
Hope it helps!
@AlexDM0 / @Jarred-Sumner the PR that fixes this issue just got merged. Now, instead of the loop, you will be warned (console.warn) about the unknown route. I would appreciate the extra eyes on this from you guys. Thank you.
Hi,
I've had issues with Android (using a Drawer with a nested scene) and iOS using a tabBar with nested scenes together with normal scenes (router here:https://github.com/crownstone/CrownstoneApp/blob/master/js/router/RouterIOS.js#L35)
I solved this by going into nested sets to find the key:
https://github.com/crownstone/CrownstoneApp/blob/master/js/router/store/reducers/navigation.ts
Basically, I reconstruct the state to have only the scene I'm at and the target scene, then use a normal back action to have the animation.
I think it's a little shortsighted to only compare the routename and not account for nesting... If you have a router like:
<Router>
<Scene key="1" />
<Drawer key="drawer">
<Scene key="2" initial={true} />
</Drawer>
</Router>
Then do Actions.1(), to go from 2 -> 1, then Actions.popTo(2) and it fails.
Cheers
Most helpful comment
@Jarred-Sumner I am able to reproduce the error - but it seems to be related to
react-navigation. But I believe something can be done over it to avoid that. I will spare some time this week to investigate this issue. Thank you.