Using the navigator, i've been trying to integrate flux with my components. The tricky thing is, i don't have an event or method to hook into for removing the event listener. I've managed to hack around it a bit by removing the listener when i push the route. Likewise from there passing a component as a back button that has this top level component in scope:
class ProjectList extends Component {
_onChange(project) {
this._unsub();
this.props.navigator.push({
component: Project,
props: { project: project },
navigationBar: (<NavigationBar
title={project.title}
titleColor="#000000"
style={appStyles.navigator}
customPrev={<CustomPrev onPress={() => {
this.props.navigator.pop();
this._sub();
}} />}
/>)
});
}
}
Which is rather ugly in my opinion. The this inside the onPress is the instance of the ProjectList
Yeah @vjeux @brentvatne are there any plans or workaround to implement this?
My use case:
I have the initial view in my app with a full screen background. I want to hide statusbar when user is on this page.
componentWillUnmountonly works if your view is the last one in the stack (e.g. you display a popup and then user can't go elsewhere but backwards. You dopopin such a case and then, component is obviously unmounted). In case your view is not the last one in your routing and user will transition to one of them withpushthere's no (?) clear way to do this as your component will stay somewhere in the stack which is totally normal and iOS-idiomatic.
What I am looking for is viewWillDisappear and viewWillAppear bindings. I am not sure if adding componentWillDisappear is a good way to do this, but having Navigator checking for a specific method and if present, calling it would've been awesome. I'll play around with Navigator api in a bit to see if there are some places I can hook into (maybe proxying call to push and calling current component method would've done the trick?)
Another possibility - passing prop isVisible, then we can use good old componentWillReceiveProps and do whatever we want.
cc @ericvicenti @hedgerwang
@agmcleod :
We're working on improving the event flow for the navigation.
Soon you'd be able to observe the route change events within the Navigator or from its owner.
For instance:
class UProjectList extends React.Component {
componentWillMount() {
var context: NavigationContext = this.context.navigationContext;
this._subscriptions = [
context.addListener('willchange', (event: NavigationEvent) => {
console.log(event);
}),
context.addListener('change', (event: NavigationEvent) => {
console.log(event);
}),
];
}
}
@hedgerwang sounds good!
Hi there! This issue is being closed because it has been inactive for a while.
But don't worry, it will live on with ProductPains! Check out it's new home: https://productpains.com/post/react-native/navigator-push-should-unmount-component-or-have-an-event-to-listen-to-pop-should-remount-the-component-its-moving-to
Is it fixed? Or just closed because it's okay to have a memory leak within an app?
@pukhalski - man, we are doing our best here, passive aggressive comments aren't helpful or appreciated :(
Yes the issue that this was created for has been fixed: "push should unmount component or have an event to listen to. Pop should remount the component it's moving to." -- there is an event to listen to, navigationContext.addListener('didfocus') and willfocus.
There is actually a good reason for keeping these views mounted in React -- on iOS for example you want to be able to use the swipe gesture to go back to a previous scene without having to re-render that scene (potentially expensive to do) and lose its state (bad ux).
A memory usage optimization for ListView is to automatically apply removeClippedSubviews, which will unmount the native views outside of the ScrollView content container clip rect (which will free up memory in the case of images), however there are no such optimizations for Navigator at the moment. See this discussion for details and a workaround: https://www.facebook.com/groups/react.native.community/permalink/710415322427382/
See @deanmcpherson's comment at the end:
I also played wiith unmounting entire navigator views , but found that it had sketchy performance for me when navigating back quickly as it had to remount whole views on the fly (probably only an issue because people tend to navigate back quicker than they go forward).
My apologies, @brentvatne. Thanks for the entire explanation.
The issue is that I have a list of 5K items on the first screen of my app, and I was using push/pop all the time to return back to the first screen with this huge list, which caused a recreation of this list each time I return back to this screen. After replacing pop with jumpTo/jumpBack, the issue disappeared.
I'm going to play with it one more time with up-to-date version of React Native.
Thanks one more time!
so what did you end up doing @pukhalski ?
Sorry for the probable offtopic but I'm having an issue that maybe it's related to this one:
I render the scene A that has a X component, the component is mounted and works as expected. Then I make a navigator push to the scene B that also has a X component (with different props) but this time, the component is not mounted and it results in a strange behaviour.
Do you think this is related to the issue being discussed?
Most helpful comment
@pukhalski - man, we are doing our best here, passive aggressive comments aren't helpful or appreciated :(
Yes the issue that this was created for has been fixed: "push should unmount component or have an event to listen to. Pop should remount the component it's moving to." -- there is an event to listen to,
navigationContext.addListener('didfocus')andwillfocus.There is actually a good reason for keeping these views mounted in React -- on iOS for example you want to be able to use the swipe gesture to go back to a previous scene without having to re-render that scene (potentially expensive to do) and lose its state (bad ux).
A memory usage optimization for ListView is to automatically apply
removeClippedSubviews, which will unmount the native views outside of the ScrollView content container clip rect (which will free up memory in the case of images), however there are no such optimizations for Navigator at the moment. See this discussion for details and a workaround: https://www.facebook.com/groups/react.native.community/permalink/710415322427382/See @deanmcpherson's comment at the end: