1

It's easy to get a reference to navigator in the renderScene function, so calling navigator.push(newRoute) is simple when responding to an event that happens from within the JSX tree.

In my case, though, I want to call navigator.push(newRoute) from an external event. My app signs the user in with Google and fires an event when the sign-in is complete, and I want to navigate to a new route in that case.

How can I get a reference to the navigator? Is there any way to get it besides as a parameter to renderScene?

Riley Lark
  • 20,660
  • 15
  • 80
  • 128

1 Answers1

1

You can get the navigator through refs property: https://facebook.github.io/react/docs/more-about-refs.html. It's part of react (not specific to react native). It's not obvious from the react-native docs that there is a number of 'react' features that can be used in react-native, so i'd really advise to take a close look at react in general.

Note however, there is a good reason Facebook does not mention refs explicitly and loudly. Refs is really not a "go-to" way of accessing component. Your case might be of course different, but it's likely that the Google sign-up is not in-fact "external". It might actually be part of one of the components in the hierarchy tree above the navigator (in which case you can pass the state change down the tree).

Quoting from the summary of the "More about refs" document above:

If you have not programmed several apps with React, your first inclination is usually going to be to try to use refs to "make things happen" in your app. If this is the case, take a moment and think more critically about where state should be owned in the component hierarchy. Often, it becomes clear that the proper place to "own" that state is at a higher level in the hierarchy. Placing the state there often eliminates any desire to use refs to "make things happen" – instead, the data flow will usually accomplish your goal.

Again - your case might be different and using refs might be perfectly justified, but if you are tempted (for example) to separate out all the Google-related stuff to separate object and if that makes the sign-up "external" - think twice. React really encourages putting all things related to a "component" logic in one place (the component) - even if that includes various technologies and external APIs.

Jarek Potiuk
  • 19,317
  • 2
  • 60
  • 61
  • Thanks for the great answer. For the navigator specifically it seems like we don't get the tools we need to keep something like google signin internal. Ideally my flux store would update with a `signedIn: true` and then something would notice that and `navigator.push(newSignedInRoute)`. With components I define myself, I can use `componentDidMount` to add new listeners to my stores and other "external" things. With the navigator, the only place I seem to get a natural reference is in `renderScene`. Would you recommend adding/removing change handlers in `renderScene`? – Riley Lark Jul 26 '15 at 21:34
  • To clarify my case a little bit, I have a GoogleSigninButton which, when clicked, calls into some native objective c code to do some GoogleSigninShenanigans. The response from objective c comes back to JS through an event. I suppose I could have the GoogleSigninButton (which could have a natural context for `navigator`) listen for that event and call a callback which in turn navigates to a new route... but again I'd rather have a store emit a `changed` event and navigate in response to that. – Riley Lark Jul 26 '15 at 21:37
  • I agree emiting events and having the store is good react pattern. I struggled a bit myself with similar use of Navigator. One of the ways that might work, is doing a bit of composition + using ref internally similarly to the accepted answer in: http://stackoverflow.com/questions/25720595/extending-react-js-components . The outer component can have it's ```componentDidMount```, and internally it uses ref to get Navigator's reference. It's a bit leaky as ref can be used outside, but then the component can have additional logic (signing) and it can be used standalone. – Jarek Potiuk Jul 27 '15 at 08:26
  • Perfect, that's what I settled on. Thanks again Jarek – Riley Lark Jul 27 '15 at 17:19