Joseph Richardo
Joseph Richardo

Reputation: 25

Move to selected pages in React Native

I have a stack navigator that looks like this:

const MainNavigator = createStackNavigator({
  Home: {screen: HomeScreen},
  Profile: {screen: ProfileScreen},
  Page1: {screen: Page1},
  Page2: {screen: Page2},
  Page3: {screen: Page3},
  Page4: {screen: Page4},
  Page5: {screen, Page5},
});

const App = createAppContainer(MainNavigator);

export default App;

From HomeScreen I go to ProfileScreen by clicking a button:

class HomeScreen extends React.Component {
    render() {
      const {navigate} = this.props.navigation;
      return (
        <Fragment>
        <Button
          title="Go to Jane's profile"
          onPress={() => navigate('Profile', {name: 'Jane'})}
        />
        </Fragment>
      );
    }
  }

On ProfileScreen I want to select some custom pages in a list, like for example Page1, Page3 and Page4. Then using a Next Button on ProfileScreen I want to go to Page1. Using a Next Button on Page1 I want to go on next selected page, Page3. Then using a Next Button on Page3 I want to go on next selected page, Page4.

How can I achieve this functionality in React native?

Upvotes: 2

Views: 1065

Answers (2)

Farhan Haque
Farhan Haque

Reputation: 1011

As already explained, react-navigation allows you to pass params when doing navigation.

This is ProfileScreen page. Here you can setup the page selection UI and setup the rest of navigation. I have tried to explain it using comments. Hope it helps.

class ProfileScreen extends React.Component {
  state = {
    pages:["page1","page2","page3","page4","page5"], // pre-define all your pages. Also make sure to add all the routes for each page
    selectedPages:[] // initially blank
  }
  render() {
    const { navigate } = this.props.navigation;
    const { pages, selectedPages } = this.state;
      return (
        <Fragment>
        <Text>ProfileScreen</Text>
        {
          // render a list of clickable page selector
          pages.map(page => {
            return(
              <TouchableOpacity key={page} onPress={() => {
                if(selectedPages.includes(page)){
                  // deselect the page, update the state and sort it.
                  this.setState({
                    selectedPages:selectedPages.filter(selectedPage => selectedPage!=page).sort()
                  })

                }else{
                  // select the page, update the state and sort it.
                  this.setState(prevState => ({
                      selectedPages:[...prevState.selectedPages, page].sort()
                  }))
                }
              }}>
                <Text style={{padding:20,backgroundColor:selectedPages.includes(page)?"green":"#ddd",marginVertical:2}}>{page}</Text>
              </TouchableOpacity>
            )
          })
        }
        <Button
          title="Go to next page"
          onPress={() => {
            if(selectedPages[0]){ // if selection contains atleast 1 page, pass the list of selected pages and the index of next page.
                navigate(selectedPages[0], {selectedPages:selectedPages, nextIndex:1})
            }else{
              // in case no page is selected
              Alert.alert("Please select atleast 1 page");
            }
          }}
        />
        </Fragment>
      );
  }
}

This is the code for page1. All pages will contain exact same code.

const Page1 = (props) => {
  const { navigate } = props.navigation;
  const selectedPages = props.navigation.getParam('selectedPages'); // get selected page list
  const nextIndex = props.navigation.getParam('nextIndex'); // get index of next page to load
  return(
    <Fragment>
      <Text>Page 1</Text>
      <Button
        title="Go to next page"
        onPress={() => {
          if(selectedPages[nextIndex]){
              // if there is more page to display pass the list of selected pages and next index
              navigate(selectedPages[nextIndex], {selectedPages:selectedPages, nextIndex:nextIndex+1})
          }else{
            Alert.alert("No more page left");
          }
        }}
      />
    </Fragment>
  )
} 

And finally the navigation

const AppNavigator = createStackNavigator({
  home: HomeScreen,
  profile: ProfileScreen,
  page1: Page1,
  page2: Page2,
  page3: Page3,
  page4: Page4,
  page5: Page5
},
  {
    initialRouteName: 'home',
}); 

I hope it helps.

Upvotes: 2

D. H Luong
D. H Luong

Reputation: 1356

react-navigation allows you to pass params when doing navigation: https://reactnavigation.org/docs/en/3.x/navigation-prop.html#navigate-link-to-other-screens.

In your case can be done like so:

class ProfileScreen extends React.Component {
state = {
  selectedScreen: 'Page3',
  nextSelectedScreen: 'Page4' // You implement your own logic of selecting the list for selected and next selected screen
}

    render() {
      const {navigate} = this.props.navigation;
      return (
        <Fragment>
        <Button
          title="Go to next selected screen"
          onPress={() => navigate(this.state.selectedScreen, {nextSelectedScreen: this.state.nextSelectedScreen})}
        />
        </Fragment>
      );
    }
  }

Then in either Screen3 or Screen4 you can do:

class Screen3 extends React.Component { // The logic is similar in Screen4

    render() {
      const {navigate, getParam} = this.props.navigation;
      return (
        <Fragment>
        <Button
          title="Go to next selected screen"
          onPress={() => navigate(getParam('nextSelectedScreen'))} // The key nextSelectedScreen was passed on the ProfileScreen
        />
        </Fragment>
      );
    }
  }

Upvotes: 2

Related Questions