Reputation: 25
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
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
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