Is there any simple way to have onEnter / onExit hooks inside navigation scenes components? It's very useful to have it because it gives the ability to create fancy animation effects.
At the moment I can see the only solution is passing props from root component and then process them inside componentWillReceivePropsof scenes component but it's super-ugly. Maybe there is some easy way to handle it with callbacks, something like <Scene onEnter={() => this.sceneComponentRef.onEnter()} />?
Yes, use Actions.refs.SCENE_NAME to refer to your component instance
@aksonov Thanks a lot for hint. Works great for onExit hook, but unfortunately, there is no component instance in Actions.refs yet on onEnter hook. Is there any workaround?
Is there a way to change state and props of rendered component with onEnter/onExit? Currently i can only read pros and state with onExit/onEnter hook using Action.refs.SCENE_NAME @aksonov
@todorone, @Megamind2301 It could be good enhancement - ability to define non-static onEnter/onExit methods.
@aksonov Can you provide a sample code using onEnter inside a component?
Thanks
@aksonov - I know you said that using componentDidMount is an anti-pattern, but it's the only easy way right now to actually modify the navbar.
I'm pretty sure other users are doing the following:
I'm actually thinking of completely giving up on the build-in navBar as it is too complicated to change the title and what the buttons do. Rendering a custom Navbar in each component looks like less work right now.
@luco it is not implemented yet, but it is not difficult to add, check sources (within createWrapper function), feel free to submit PR.
Same thing would be very useful for onLeft & onRight (onBack?) callbacks
It will be more difficult for onLeft/onRight/onBack - you could just use Actions.refs.SCENE_NAME to access your component
can i use define non-static onEnter/onExit methods now?
if i have two same screen in my routestack,for example A B A C,when i back A from C, how can i discriminate which A i focus?
with the same problem with @Tomatoo ,My routestack is A->A->A->A->A,with different programs,but the Actions.refs just have one instance with A,So I doesn't know which A pop and Which Enter.
@aksonov Thanks a lot for recent onEnter / onExit as scene's instances methods implementation. Unfortunately, onEnterbehavior is little bit of quirky - it works only when component is mounted(created first time), but when, for-example, a user navigates to already created scene, the scene is entered but onEnter is not invoked so it may be misleading...
Hope what I've described makes sense... 😺
You are right... Need to think how to implement it in better way..
@aksonov Btw, fixed onExit which is never invoked right now - #2759
Thanks, but please also run npm run build to recompile ES5-sources too.
@aksonov Sorry, missed it. #2760
@aksonov ( Yes, use Actions.refs.SCENE_NAME to refer to your component instance)
can you show me the code please? I still have no idea
@aksonov Pretty good news. At last, lifecycle events system is currently being implemented in react-navigation so hopefully, with next release, we can reimplement onEnter/onExit hooks in more reliable and elegant way.
https://github.com/react-navigation/react-navigation/pull/3345
render() {
return (
<Router>
<Stack key="root">
<Scene key="login" hideNavBar={true} component={LoginPanel} />
<Tabs key="table" tabBarPosition='bottom' headerMode='screen' titleStyle={{ alignSelf: 'center' }}>
<Scene key="TimeCard" onEnter={() => this.onEnter()} title='TimeCard' component={FirstScreen} />
<Scene key="Joho" onEnter={() => this.onEnter()} title='Joho' component={MeisaiJoho} />
<Scene key="Me" onEnter={() => this.onEnter()} title='Me' component={MePanel} />
</Tabs>
<Scene key="Change" component={MeisaiChange} />
<Scene key="Me2" component={MePanel2} />
</Stack>
</Router>
);
}
onEnter() {
Actions.refresh({action:new Date().getTime()});
}
md5-3c7a5964f8b818ccf6d97a662c549184
componentWillReceiveProps(nextProps: Readonly<P>, nextContext: any){
console.log("FirstScreen ReceiveProps");
}
This can be achieved refresh function, Actions.refresh ({action: new Date (). GetTime ()}); The value passed must be changed, otherwise it will not trigger the componentWillReceiveProps event
Now I found that this method works only on android, ios does not work
Yoohooo!
We have latest React Navigation release with exciting blur/focus events system.
No more hacks and inconsistent onEnter/onExit behavior, we just need to adopt the new system to RNRF.
Really good news, finally we could release v4 without beta too, does anyone have time to write PR, it should not be difficult I guess...
On 8 Feb 2018, at 09:39, Todor1 notifications@github.com wrote:
Yoohooo!
We have latest React Navigation release with exciting blur/focus events system - react-navigation/react-navigation#3345 https://github.com/react-navigation/react-navigation/pull/3345
No more hacks and inconsistent onEnter/onExit behavior, we just need to adopt the new system to RNRF.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub https://github.com/aksonov/react-native-router-flux/issues/2298#issuecomment-364040172, or mute the thread https://github.com/notifications/unsubscribe-auth/ABQpcXkpsXs5iPrZbbziRMtfnecV336mks5tSrK4gaJpZM4PE5OG.
When is it released? onEnter={() => this.onEnter()}Why is it working fine in android, but not in ios?
@aksonov
This is starting to work for me after adding a static onExit method to my component.
I see 'onExit' in logs for both Android and iOS.
<Stack key="login" path="login/:data" titleStyle={{ alignSelf: 'center' }}>
<Scene
key="loginModal"
component={Login}
title="Login"
onExit={() => { Login.onExit()}
leftTitle="Cancel"
onLeft={Actions.pop}
/>
Using:
"react": "^16.2.0",
"react-native": "^0.53.3",
"react-native-router-flux": "4.0.0-beta.27",
You can try to use Actions.refs.SCENE_NAME to access component instance
@aksonov can show me a example how to use Actions.refs.SCENE_NAME
@aksonov can show me a example how to use Actions.refs.SCENE_NAME
Not sure if this will help but I solved this in my case where i wanted an api to be called every time i enter a screen that has already been mounted:
static onEnter() {
if (Actions.refs.itemList !== undefined) {
Actions.refs.itemList.selector.props.searchItems()
}
}
Where searchItems is a redux action mapped using connect(mapStateToProps, {searchItems}) in the same component
@JonathanLouw Thanks!! This also work for me. In my case the object structure was a bit different the what you're showing here but work it! Thanks one more time!
I think about this questions,use redux can fix all of them
@aksonov can show me a example how to use Actions.refs.SCENE_NAME
Not sure if this will help but I solved this in my case where i wanted an api to be called every time i enter a screen that has already been mounted:
static onEnter() { if (Actions.refs.itemList !== undefined) { Actions.refs.itemList.selector.props.searchItems() } }Where searchItems is a redux action mapped using
connect(mapStateToProps, {searchItems})in the same component
I spent 5 hours trying to solve this problem and your solution is the only one which worked. The only change I made is putting that code into the onEnter prop of the Scene, here is my code:
<Scene
key="careers"
component={Careers}
onEnter={() => {
if (Actions.refs.careers !== undefined) {
Actions.refs.careers.selector.props.fetchCareersList();
}
}}
/>
@aksonov can show me a example how to use Actions.refs.SCENE_NAME
Not sure if this will help but I solved this in my case where i wanted an api to be called every time i enter a screen that has already been mounted:
static onEnter() { if (Actions.refs.itemList !== undefined) { Actions.refs.itemList.selector.props.searchItems() } }Where searchItems is a redux action mapped using
connect(mapStateToProps, {searchItems})in the same component
Thank you my friend! You saved my day. For me it worked perfectly!
i've tried all suggestion here but failed, because my case is inside a tabs. recently i found solution from https://stackoverflow.com/questions/49005289/reload-screen-when-the-tab-is-changed to use didFocus listener. here is the code:
class YourComponent extends Component {
componentDidMount() {
this.didFocusListener = this.props.navigation.addListener(
'didFocus',
() => { console.log('did focus') },
);
}
componentWillUnmount() {
this.didFocusListener.remove();
}
render() {
return ( /* your render */ );
}
}
any working code example please ?
Most helpful comment
@aksonov Can you provide a sample code using
onEnterinside a component?Thanks