Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Navigator] push should unmount component or have an event to listen to. Pop should remount the component it's moving to. #1731

Closed
agmcleod opened this issue Jun 24, 2015 · 12 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@agmcleod
Copy link

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

@grabbou
Copy link
Contributor

grabbou commented Jul 20, 2015

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. componentWillUnmount only 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 do pop in 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 with push there'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?)

@grabbou
Copy link
Contributor

grabbou commented Jul 20, 2015

Another possibility - passing prop isVisible, then we can use good old componentWillReceiveProps and do whatever we want.

@vjeux
Copy link
Contributor

vjeux commented Jul 20, 2015

cc @ericvicenti @hedgerwang

@hedgerwang
Copy link

@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);
      }),
    ];
  }
}

@agmcleod
Copy link
Author

@hedgerwang sounds good!

@brentvatne
Copy link
Collaborator

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

@pukhalski
Copy link

Is it fixed? Or just closed because it's okay to have a memory leak within an app?

@brentvatne
Copy link
Collaborator

@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).

@pukhalski
Copy link

My apologies, @brentvatne. Thanks for the entire explanation.

@pukhalski
Copy link

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!

@antoinerousseau
Copy link
Contributor

so what did you end up doing @pukhalski ?

@jpamarohorta
Copy link

jpamarohorta commented Dec 21, 2016

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?

@facebook facebook locked as resolved and limited conversation to collaborators Jul 22, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 22, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests

9 participants