Hello!
After migrating from v3 to v4 I see this problem:
When push 3 scenes to stack and then go back with Actions.pop() 3 times lifecycle methods will be called on same components again after unmount.
My guess that is component will get remounted and then immedeately unmounted.
index.ios.bundle?platform=ios&dev=true&minify=false:164287 componentDidMount
index.ios.bundle?platform=ios&dev=true&minify=false:164298 componentDidUpdate
index.ios.bundle?platform=ios&dev=true&minify=false:164298 componentDidUpdate
index.ios.bundle?platform=ios&dev=true&minify=false:164298 componentDidUpdate
index.ios.bundle?platform=ios&dev=true&minify=false:164308 componentWillUnmount
index.ios.bundle?platform=ios&dev=true&minify=false:164279 componentWillMount
index.ios.bundle?platform=ios&dev=true&minify=false:164287 componentDidMount
index.ios.bundle?platform=ios&dev=true&minify=false:164308 componentWillUnmount
Tell us which versions you are using:
Components lifecycle methods called again ComponentWillMount/DidMount/WillUnmount
Should not call lifecycle methods after unmount.
For non-obvious bugs, please fork this component, modify Example project to reproduce your issue and include link here.
for ( let x in new Array(3).fill() ) {
await Actions.pop();
}
Are these nested same Scenes? Cause react 16 talks about something that might be related to this (out of order calls).
Component Lifecycle
Since React prioritizes the rendering, you are no longer guaranteed componentWillUpdate and shouldComponentUpdate of different components will fire in a predictable order. The React team is working to provide an upgrade path for apps that would break from this behavior.
Source: https://edgecoders.com/react-16-features-and-fiber-explanation-e779544bb1b7
@daviscabral Hello!
When I do Actions.pop components that should just unmount will unmount and remount and unmount again. I don't think it's React related
I see. Are you using redux? I am asking to see if Is there any way to track the page actions.
@kesha-antonov Looks like your Router is not top-level and you are recalling it, probably with different params. I tried to reproduce your issue with Example provided by this component without success (from Login3 page). Please fork and modify Example as requested initially.
@daviscabral I use mobx.
@aksonov Thank you for looking at it. I'll provide an example.
I have
<View>
<Router ...>
{this.scenes()}
</Router>
...other Components
</View>
Ok. Solved it with other way
Closing for now
It's definitely something wrong @aksonov
Because when I call Actions.tabbar({ type: ActionConst.RESET })
(see https://github.com/aksonov/react-native-router-flux/issues/2595)
it remounts signIn scene twice. I think this is also cause of this error: Could not locate shadow view with tag #122, this is probably caused by a temporary inconsistency between native views and shadow views.

Now try to do the same with pure react-navigation and check results. RNRF doesn't do almost any rendering.
Ok. Maybe it's my app related.
I found out that my App and Router re-renders after sign in.

What's be best way to solve it?
If you need to re-render component with Router. But not Router itself @aksonov
Ok. Rewrote without re-render
Same errors
When I disabled Actions.refresh on scene where I go from signIn errors disappear. SignIn will unmount and no errors/warnings.
Something wrong with Actions.refresh
Wrapping Actions.refresh in `InteractionManager.runAfterInteractions helped. No errors/warnings
So I think they appear if Actions.refresh called on new scene when previous is not unmounted yet. What do you think? @aksonov
Ref: https://github.com/react-community/react-navigation/issues/2702
--- UPDATE ---
Yes. Errors/warnings disappear when previous scenes is unmounted completely (componentWillUnmount called).
If prev scene is not unmounted (componentWillUnmount not called yet) and we call Actions.refresh on the next scene - then prev scene get's remounted twice and errors/warnings appear.
This happens with Actions.pop and Actions.tabbar({ type: 'reset' })
It looks very useful, could you submit PR?
Wrapping Actions.refresh in
InteractionManager.runAfterInteractionshelped. No errors/warnings
This is bad idea. If you're talking about this.
We should detect that prev scene is unmounted componentWillUnmount called and if not skip setProps in Actions.refresh
Have you tried just to wrap it with setTimeout ?
No. Now I track it in mobx store
Good suggestion
@aksonov
Yes. setTimeout works
But if I use
refresh = (data) => {
const key = getActiveState(this._state).key;
const params = filterParam(data);
setTimeout(() => {
this.dispatch(NavigationActions.setParams({ key, params }));
})
};
for all scenes I see delay of rendering title, navbar buttons.
So this is what is going on:
Actions.tabbar({ type: 'reset', ... })
componentDidMount in scene_2Actions.refreshscene_1 is not unmounted yet setParams is called on that scenecomponentWillUnmount, componentDidMount, componentWillUnmount called on scene_1@kesha-antonov It is interesting. We could easily modify our Reducer and process SET_PARAMS by RNRF (not to forward to RN). Could you try @gaodeng receipt?
Tried but didn't understand RNRF code.
Can you please help try adapt that code? @aksonov
Sorry, don't have time. You may check Reducer.js and its code. For many actions it just forwards requests to navigationStore.router.getStateForAction. You may add own if else block for REFRESH action (and remove it from supportedActions map)
Ok. Thanks! I'll find solution.
Closed because it is not related to RNRF.
i have the same problem,use Actions.pop({refresh: {update: new Date()}})銆倃hat i should do
@kesha-antonov hi, do you found any solution for this? my current workaround is by adding setTimeout(() => { Actions.productListing({type: 'replace'}), 0);. But it still give me flicker effect. Another workaround is by adding a custom loader before the next scene mounted. But the loader will always be rendered everytime the next scene is called.
UPDATE:
Found the best solution so far by rendering an empty View, before navigating to the next scene.
shouldComponentUpdate(nextProps, nextState) {
if (nextProps.status === 'ACTIVE') {
Actions.productListing({ type: 'replace' });
};
return true;
};
render() {
if (this.props.status === 'ACTIVE') {
return <View></View>;
} else {
return this.renderSubmitRegistration();
}
};
Hello @fadlykayo ! I've migrated to react-navigation today
Most helpful comment
Hello @fadlykayo ! I've migrated to react-navigation today