James Ko
James Ko

Reputation: 34489

How to pass props to component inside a React Navigation navigator?

I'm trying to pass props to a component that has been wrapped through a call to create...Navigator call, i.e.

// Search.js
const Navigator = createMaterialTopTabNavigator({
    Wines,
    Stores,
    Vineyards,
    Restaurants
});

// Somewhere in render()...
<Navigator />

I'm trying to figure out how to pass parameters to the Wines / Stores / etc. components from the Search component (above). I've read the docs and apparently this can be done easily with navigation.navigate by passing in an object, but I'm not sure how to do it with this particular method. Can someone please help?

Upvotes: 26

Views: 31508

Answers (2)

vindom
vindom

Reputation: 499

Based on this you can pass properties to screens also like this:

return (
    <NavigationContainer>
      <Tab.Navigator>
            <Tab.Screen name="Home">
                {(props) => <HomeScreen  {...props} text={homeText} />}
            </Tab.Screen>
           <Tab.Screen name="Settings" component={SettingsScreen} />
      </Tab.Navigator>
    </NavigationContainer>
  );

The difference to the following method from the docs

            <Tab.Screen name="Home" component={HomeScreen} />

is this:

            <Tab.Screen name="Home">
                {(props) => <HomeScreen  {...props} text={homeText} />}
            </Tab.Screen>

This worked just fine for me in a similar case.

Upvotes: 23

bennygenel
bennygenel

Reputation: 24660

Your example is a bit vague so I try to explain as much as I can.

There is 2 different ways to pass properties to screens (except redux implementation).

1) navigate action

You can pass parameters to navigated screen with passing params argument to the screen.

navigation.navigate({routeName, params, action, key}) OR navigation.navigate(routeName, params, action)

routeName - A destination routeName that has been registered somewhere in the app's router

params - Params to merge into the destination route

action - (advanced) The sub-action to run in the child router, if the screen is a navigator. See Actions Doc for a full list of supported actions.

key - Optional identifier of what route to navigate to. Navigate back to this route, if it already exists

Sample

this.props.navigate('Profile', { name: 'Brent' })

2) screenProps

You can pass a global parameter to the navigation which can be available in every screen for that navigation.

screenProps - Pass down extra options to child screens

Sample

const SomeStack = createStackNavigator({
  // config
});

<SomeStack
  screenProps={/* this prop will get passed to the screen components as this.props.screenProps */}
/>

I have created a small sample app which I am guessing you are trying to achieve.

const Tab = ({name, searchValue}) => (
  <View style={styles.tabContainer}>
    <Text>{name}</Text>
    <Text>{`Searching: ${searchValue || '...'}`}</Text>
  </View>
);

const Wines = (props) => (<Tab name="Wines Page" searchValue={props.screenProps.searchValue} />);
const Stores = (props) => (<Tab name="Stores Page" searchValue={props.screenProps.searchValue} />);
const Vineyards = (props) => (<Tab name="Vineyards Page" searchValue={props.screenProps.searchValue} />);
const Restaurants = (props) => (<Tab name="Restaurants Page" searchValue={props.screenProps.searchValue} />);

const Navigator = createMaterialTopTabNavigator({
    Wines,
    Stores,
    Vineyards,
    Restaurants
});

export default class App extends Component {
  state = {
    text: ''
  }
  changeText = (text) => {
    this.setState({text})
  }
  clearText = () => {
    this.setState({text: ''})
  }
  render() {
    return (
      <View style={styles.container}>
        <SearchBar
          lightTheme
          value={this.state.text}
          onChangeText={this.changeText}
          onClearText={this.clearText}
          placeholder='Type Here...' />
        <Navigator screenProps={{searchValue: this.state.text}} />
      </View>
    );
  }
}

Upvotes: 21

Related Questions