'Pass Props StackNavigator

i try to pass props on stacknavigator, here my code

const MainCart = StackNavigator({
  Cart: {
    screen: CartScreen
  },
  Checkout: {
    screen: COScreen
  }

  /* how to pass 'myprops' in this area? */

});


export default class ReactNative_RefreshControl extends Component {

  constructor(props) {
    super(props)
  }

  render() {
    console.log('ReactNative_RefreshControl this.props.myparam : ' + this.props.myparam);
    return <MainCart myprops = {
      this.props.myparam
    }
    />;

    //https://reactnavigation.org/docs/navigators/stack#Navigator-Props
  }


}

how to pass 'myprops' on StackNavigator area?

thanks



Solution 1:[1]

React Navigation < 5

If you want to pass props in that place you have to use it like this.

const MainCart = StackNavigator({
 Cart: {
    screen: props=> <CartScreen {...props} screenProps={other required prop}>
 },
 Checkout: {
    screen: COScreen
 }

If you want to pass props when navigating the solution by Sagar Chavada is useful

React Navigation - 5

You have to either use React Context(recommended) or a render callback to solve this. Documentation link

Below example shows how to do with React Context

In your parent of the navigator file create a context

<AppContext.Provider value={other required prop}>
   <YourNavigator/>
</AppContext.Provider>

In your navigator file

const YourNavigator = () => (
  <AppStack.Navigator>
     <AppScreen.Screen name={"routeName"} component={AppContextWrapper}/>
  </AppStack.Navigator>

const AppContextWrapper = ({ navigation, route }) => (
  <AppContext.Consumer>
    {(other required prop) => (
       <YourScreenComponent {...other required prop}/>
    )}
  </AppContext.Consumer>
);

another easy (not recommended) - Callback method

<Stack.Screen name="Home">
  {props => <HomeScreen {...props} extraData={someData} />}
</Stack.Screen>

Note: By default, React Navigation applies optimizations to screen components to prevent unnecessary renders. Using a render callback removes those optimizations. So if you use a render callback, you'll need to ensure that you use React.memo or React.PureComponent for your screen components to avoid performance issues.

Solution 2:[2]

For those who are looking for React Navigation 5

<Stack.Navigator initialRouteName="LoginScreen" headerMode="none">
 <Stack.Screen name="LoginScreen" component={LoginScreen} initialParams={{'key':'value'}} />
 <Stack.Screen name="CodeVerificationScreen" component={CodeVerificationScreen} initialParams={{'key':'value'}} />
</Stack.Navigator>

You can receive initial params in login.js

console.log(this.props.route.params.key)

Solution 3:[3]

**React-navigation v3**

in your click event do like this:

    onPressed(movie){
        this.props.navigation.navigate(
          'screen',
          {movie: movie}
        });
      }

<TouchableHighlight onPress={() => this.onPressed(movie)}>

and in other screen you can set like this:

export default class NavigateTo extends Component {
  constructor(props){
    super(props);

    this.state = {
        name: this.props.navigation.state.params.movie.title,
        year: this.props.navigation.state.params.movie.year
    }
  }

movie is a json object that contain title, year, release date, earning, poster, etc..

this one is for old navigation:

onPressed(movie){
    this.props.navigator.push({
      id:'page2',
      movie: movie
    });
  }

and in second screen:

this.state = {
        name: this.props.movie.title,
        email: this.props.movie.year
    }

now you can see the difference

if this not work than try like this

<Button title="Second" onPress={() => navigate("MainCart",{},
  {
    type: "Navigate",
    routeName: "Checkout",
    params: {name:"Jo"}
  }
)} />

check this for nested stack navigation https://github.com/react-community/react-navigation/issues/143

Solution 4:[4]

In my case I wanted to pass a function to show toast with conte for every component, I ended up achieving it by using screenProps and overriding each component:

export default class App extends React.Component {
  constructor(props) {
  super(props);
}

showToast = (text) => {
  this.refs.toast.show(text, DURATION.FOREVER);
};

render() {
  return <Provider store={store}>
    <View style={styles.wrapper}>[
      <MyAppNavigator showToast={this.showToast}/>,
      <Toast ref="toast"/>
      ]
    </View>
  </Provider>;
  }
}

const styles = StyleSheet.create({
  wrapper: {
    flex: 1
  }
});


const createNavigator = (screenProps) => {
  const toastWrapper = (Component, props, screenProps) => {
    return <Component {...props} screenProps={screenProps}/>
  };
  return createStackNavigator({
    login: {
      screen: props => toastWrapper(LoginView, props, screenProps),
      navigationOptions: () => {
        return {header: null}
      }
    },
    map: {
      screen: props => toastWrapper(FieldMap, props, screenProps),
      navigationOptions: () => ({
        title: 'Map'
      })
    }
  })
};

const MyAppNavigator = (props) => {
  const AppNavigator = createNavigator(props);
  return <AppNavigator/>
};

Then from my component:

this.props.screenProps.showToast("Logging you in");

Solution 5:[5]

Lets assume you want to pass the parameter myTheme via props through the navigation. On React Navigation 5 you can do so

...    
const myTheme = {...}
 return(
        <ProfileStack.Navigator initialRouteName='ProfileWithSettings'>
           <ProfileStack.Screen name={'ProfileWithSettings'}>
                {props => <ProfileWithSettings {...props} theme={myTheme}/>}
           </ProfileStack.Screen>
        <ProfileStack.Navigator/>
    );

on the ProfileWithSettings component you could then refer to myTheme as follows:

this.props.theme

Solution 6:[6]

I need to send props from main component to StackNavigator and then passing down to it's component, I used screenProps to do that.

Your main function should look like this:

render() {
    return <MainCart screenProps={this.props.params}
    />;
  }

After that in navigator screen you can access it like this:

this.props.screenProps.params

Solution 7:[7]

My previous answer holds if you are trying to access the app level from a navigation view, however, if you want to simply change the header or something like that you don't have to pass the params to your navigator.

A little bit of React magic:

export default class ReactNative_RefreshControl extends Component {
  constructor(props) {
    super(props)
  }

  //this function will override the navigation options specified in MainCart component
  static navigationOptions = ({navigation}) => {
    return {
      headerTitle: navigation.state.params.name,
      headerRight: <Button onPress={navigation.state.params.onClick}/>
    };
  };

  componentDidMount() {
    this.props.navigation.setParams({
      name: "name",
      onClick: this.onClick
    });
  }
  ...
}

Solution 8:[8]

For Passing params from children of one stackNavigator to children of another stackNavigator in v5 react-navigation

const SecondStackNavigator = props => {
const stackOptions = {};
return (
  <Stack.Navigator headerMode={"none"} screenOptions={stackOptions}>

    <Stack.Screen name={"market"}>{() => <SecondScreen {...props} />}
   //Here the props is passed with spread operator to children 

  </Stack.Screen>

); };

Solution 9:[9]

For everybody who is finding a solution for react-navigation 6.x:

According to react-navigation doc:

Passing params to a previous screen?

Params aren't only useful for passing some data to a new screen, but they can also be useful to pass data to a previous screen too. For example, let's say you have a screen with a create post button, and the create post button opens a new screen to create a post. After creating the post, you want to pass the data for the post back to previous screen.

To achieve this, you can use the navigate method, which acts like goBack if the screen already exists. You can pass the params with navigate to pass the data back:

function HomeScreen({ navigation, route }) {
  React.useEffect(() => {
    if (route.params?.post) {
      // Post updated, do something with `route.params.post`
      // For example, send the post to the server
    }
  }, [route.params?.post]);

  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Button
        title="Create post"
        onPress={() => navigation.navigate('CreatePost')}
      />
      <Text style={{ margin: 10 }}>Post: {route.params?.post}</Text>
    </View>
  );
}

function CreatePostScreen({ navigation, route }) {
  const [postText, setPostText] = React.useState('');

  return (
    <>
      <TextInput
        multiline
        placeholder="What's on your mind?"
        style={{ height: 200, padding: 10, backgroundColor: 'white' }}
        value={postText}
        onChangeText={setPostText}
      />
      <Button
        title="Done"
        onPress={() => {
          // Pass and merge params back to home screen
          navigation.navigate({
            name: 'Home',
            params: { post: postText },
            merge: true,
          });
        }}
      />
    </>
  );
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Brijesh Singh
Solution 3
Solution 4 nook
Solution 5 Jorciney
Solution 6
Solution 7 nook
Solution 8 ishab acharya
Solution 9 H. Qasemi