React-native-router-flux: Scene dynamic initial

Created on 13 Jun 2016  路  6Comments  路  Source: aksonov/react-native-router-flux

Version

  • react-native-router-flux v3.26.13
  • react-native v0.26.3

    Expected behaviour

  let isLoggedIn = this.state.isLoggedIn;

   <Scene
      key="login" component={Login} title="Login" type="reset" hideNavBar
      initial={isLoggedIn}
    />
    <Scene
      key="main" tabs default="Dashboard" tabBarStyle={colorStyles.appBg}
      initial={isLoggedIn}
    >

I hope initial is dynamic

Dynamic Routing(3.x release) allows you to choose which scene to render depending on application state , But Switch should be used together with tabs={true} property.

Most helpful comment

@cridenour how should this be achieved then?

scenes/index.js

export default Actions.create(
  <Scene
    key="root"
  >
    {Scene}
    {OtherScene}
    { /* ... more Scenes */}
  </Scene>,
);

root.js

export default function Root() {
  return (
    <Provider store={store}>
      <RouterWithRedux scenes={scenes} />
    </Provider>
  );
}

How should I switch between Scene and OtherScene depending on the state?

Should I make Root a Stateful Component and handle on component render, dispatching Actions.key?

I'm very confused and this has been taking me a lot of time to figure it out correctly.

Thanks in advance.

All 6 comments

Scene is not real component (it doesn't render nothing), so you can't use it as Component replacements. You could use it only inside Router.

Also, even inside a router you should have have state, as you should not re-render the whole app. And given that any "isLoggedIn" will be async, you should be routing to another component after determining a logged in state.

@cridenour how should this be achieved then?

scenes/index.js

export default Actions.create(
  <Scene
    key="root"
  >
    {Scene}
    {OtherScene}
    { /* ... more Scenes */}
  </Scene>,
);

root.js

export default function Root() {
  return (
    <Provider store={store}>
      <RouterWithRedux scenes={scenes} />
    </Provider>
  );
}

How should I switch between Scene and OtherScene depending on the state?

Should I make Root a Stateful Component and handle on component render, dispatching Actions.key?

I'm very confused and this has been taking me a lot of time to figure it out correctly.

Thanks in advance.

@wachunei any update on how you handled this?

@mbenjamin618 I've created an initial Scene (SplashScreenScene here) which has set an SplashScreen component that handles storage and rehydration and then redirects to corresponding scene.

This solution unfortunately eluded me for a while then hit me while in the shower. It's actually quite simple. Don't render the <Router> until you have a persisted state loaded and instead load an empty <View/> while keeping the splash screen showing (or you could use another loading Scene). I'm using this splash-screen-plugin to hide the splash once the local storage has persisted (hydrated - the term comes from redux-persist)

render() {
    const { onEnter, isLoggedIn, hydrated } = this.props;

    return hydrated ? (
        <Router
            sceneStyle={{
                backgroundColor: `white`,
            }}
        >
            <Scene
                initial={isLoggedIn}
                hideNavBar
                key={MY_WATER_KEY}
                onEnter={() => onEnter(MY_WATER_KEY)}
                component={MyWater}
                icon={({ focused }) => (
                    <TabbarTab
                        active={focused}
                        icon={`drop2`}
                        label={getLocalizedString(
                            `myWater.title`,
                        )}
                    />
                )}
            />
            <Scene
                initial={!isLoggedIn}
                key={LOGIN_SCENE_KEY}
                onEnter={() => onEnter(LOGIN_SCENE_KEY)}
                component={Login}
            />
        </Router>
    ) : <View/>;
}

My hydrated prop is coming from redux and is true when the local storage has persisted and from the persisted state I can tell if a user is logged in. If it hasn't hydrated, I just show an empty <View/> and don't hide the splash screen.

Then I used the initial prop by passing in the isLoggedIn prop to dynamically determine which to show as @dellheng suggested. If they are logged in, I send them to MY_WATER and if they're not, I send them to LOGIN. Worked like a charm.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

vinayr picture vinayr  路  3Comments

fgrs picture fgrs  路  3Comments

jgibbons picture jgibbons  路  3Comments

YouYII picture YouYII  路  3Comments

kirankalyan5 picture kirankalyan5  路  3Comments