Giter Site home page Giter Site logo

Comments (3)

fvsch avatar fvsch commented on May 4, 2024 2

Sure. A demonstration of our use case is here:
https://snack.expo.io/@screamz/react-navigation:-conditional-child-navigator

As you can see in this demo, in the redux store the navigation state doesn’t contain the routes for either the Onboarding or the actual HomeScreen. We followed a pattern we’ve seen a lot in the react-navigation bug tracker (several issues on this topic):

class HomeWrapper extends Component {
  render() {
    return (
      this.props.showOnboarding ? <Onboarding /> : <HomeScreen />
    )
  }
}

export default connect(state => ({
  showOnboarding: state.onboarding.showOnboarding
}))(HomeWrapper)

The trouble with this solution is that it "breaks" the navigation state in redux. The navigation state in redux doesn’t know if we’re on the onboarding or the home screen. And since the onboarding is a navigator itself, it becomes a disconnected root navigator.

In our actual app-in-development, our structure is a bit more complex:

ReduxNavigator {
  RootTabNavigator {
    Home,
    Foo,
    JournalRoot {
      JournalOnboarding { Step1, Step2, Step3 },
      JournalFeature { Screen1, Screen2, Settings }
    },
    Bar,
    UserProfile
  }
}

So our big difficulty was to create this JournalRoot which shows either JournalOnboarding (a navigator) or JournalFeature (another navigator), but never both, and users should not be able to navigate manually between those (e.g. with the back button).

We tried using the same pattern as above:

class JournalRoot extends Component {
  render() {
    return (
      this.props.showOnboarding ? <JournalOnboarding /> : <JournalFeature />
    )
  }
}

export default connect(state => ({
  showOnboarding: state.journal.showOnboarding
}))(JournalRoot)

This works well for the visible parts, but because our routers are not linked correctly, everything from JournalOnboarding and JournalFeature will be absent from the redux state, and we cannot e.g. navigate from the home screen to the JournalFeature/Screen1 or JournalFeature/Screen2. It also makes it difficult to use analytics correctly.

So we are trying to make a unified navigation tree (not 3 disconnected root navigators), and failing. :)

Our current workaround, which we are still testing, merges JournalOnboarding and JournalFeature in a single TabNavigator, with the onboarding part being a hidden tab (we have a custom tabbar component so it’s easy to hide it):

ReduxNavigator {
  RootTabNavigator {
    Home,
    Foo,
    JournalRoot {
      JournalTabNavigator {
        Screen1,
        Screen2,
        Settings,
        JournalOnboarding { Step1, Step2, Step3 }
      }
    },
    Bar,
    UserProfile
  }
}

And we use JournalRoot as a wrapper screen for JournalTabNavigator, forcing a navigation to the onbarding if needed:

class JournalRoot extends React.Component {
  componentDidMount() {
    this.props.navigation.addListener('willFocus', this.switchScreen)
  }
  componentWillReceiveProps(nextProps) {
    if (nextProps.showOnboarding !== this.props.showOnboarding) {
      this.switchScreen(nextProps.showOnboarding)
    }
  }
  switchScreen = (showOnboarding) => {
    showOnboarding = typeof showOnboarding === 'boolean' ? showOnboarding : this.props.showOnboarding
    this.props.navigation.navigate(
      showOnboarding ? 'JournalOnboarding' : 'Screen1'
    )
  }
  render() {
    return <JournalTabNavigator navigation={this.props.navigation} />
  }
}

const JournalRootWithState = connect(state => ({
  hasCompleteOnboarding: hasCompleteOnboarding(state)
}))(JournalRoot)

// Link the router from the wrapper to the wrapped navigation
JournalRootWithState.router = JournalTabNavigator.router

export default JournalRootWithState

This works well if our user has already seen the onboarding (no navigation), but if not we force a navigation when loading the app and this focuses the "Journal" tab, instead of staying on the "Home" tab (which is normal, but not what we want :P)

To sum up: the pattern where you use a condition to render one screen or the other is alright for single screens, but using this pattern to render one navigator or the other breaks deep navigation.

from react-navigation.github.io.

brentvatne avatar brentvatne commented on May 4, 2024

can you provide some more information on your use case? preferably code on what you're doing now, and perhaps a video or screenshots to further demonstrate

from react-navigation.github.io.

brentvatne avatar brentvatne commented on May 4, 2024

cc @ericvicenti

from react-navigation.github.io.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.