简体   繁体   中英

How to pass props to Screen component with a tab navigator?

This is my first post on StackOverflow, so apologies if I'm not following the correct format.

I'm building my first app using tab navigator from React Navigation v 5.x and have run into a big problem when passing props from one screen to another

What I want to achieve is to:

  1. Make changes to a list of data in one of my screens.
  2. Have those changes affect what happens on another screen.

I have tried this (I failed to set the props to pass down), this (Deprecated version of react-navigation) and this (Also old version of react-navigation).

and Redux but there are no examples available with the current version of react navigation.

I'm at the end of my rope with this and really need some step by step on how to achieve this. Here's a rough sketch of what I want to do:

在此处输入图像描述

The way I thought about it is sending the parent state down as props via callback, but I can't find a way to send props through the screen components in the up-to-date version of react navigation...

This is my navigation setup:

const Tab = createBottomTabNavigator()

export default class MyApp extends Component{

    constructor(props) {
        super(props);
    }

    render(){
        return (
            <NavigationContainer>
                <Tab.Navigator 
                    screenOptions={({ route }) => ({
                        tabBarIcon: ({ focused, color, size }) => {
                            let iconName;

                            if (route.name === 'My tests') {
                                iconName = focused ? 'ios-list-box' : 'ios-list';
                            } else if (route.name === 'Testroom') {
                                iconName = focused ? 'ios-body' : 'ios-body';
                            }

                            return <Ionicons name={iconName} size={size} color={color} />;
                        },
                    })}
                    tabBarOptions={{
                        activeTintColor: 'tomato',
                        inactiveTintColor: 'gray',
                            
                    }}>

                    <Tab.Screen name="My tests"  component={MyTests}/> //This is where I want to send props
                    <Tab.Screen name="Testroom" component={TestRoom} />  //This is where I want to send props
                    
                </Tab.Navigator>
            </NavigationContainer>
        )
    }
}

I've read this but it makes no sense to me. How does this fit into a tree of components? What goes where? Please help!

you can use the property 'children' to pass an element type jsx like instead of the property 'component', is recomended from react-native.

On this way you can pass props to component example:

    <tab.Screen
    name="home"
       children={()=><ComponentName propName={propValue}/>}
    />

is neccesary to use '()=>' because the property children need a function that return a jsx element, it's functional.

React Navigation version 5+

<Tab.Screen name="Work" component={Works} initialParams={{ age: 45 }} />

Can be accessed using props on the Works component.

Check out the answer in the code comments.

<Tab.Screen
  name="AdminTab"
  children={() => <AdminPage userData={this.props.userSettings} />}
  // component={() => <AdminPage userData={this.props.userSettings} />} <<<---- Although this will work but passing an inline function will cause the component state to be lost on re-render and cause perf issues since it's re-created every render. You can pass the function as children to 'Screen' instead to achieve the desired behaviour. You can safely remove the component attribute post adding children.
/>

Looks like you're passing an inline function for 'component' prop for the screen 'AdminTab' (eg component={() => <SomeComponent /> }). Passing an inline function will cause the component state to be lost on re-render and cause perf issues since it's re-created every render. You can pass the function as children to 'Screen' instead to achieve the desired behaviour.

In order to send props to <MyTests /> component, inside <Tab.Screen /> :

<Tab.Screen name="My tests">
  {() => <MyTests myPropsName={myPropsValue} />}
</Tab.Screen>
<Tab.Navigator>
   <Tab.Screen name="Lead">
   {() => <LeadList {...this.props} />}
   </Tab.Screen>

   <Tab.Screen name="Opportunity">
   {() => <OpportunityList {...this.props} />}
   </Tab.Screen>
</Tab.Navigator>

I also need the pass a function to screen in order to render the popup on all screens but it is required to show the popup from a specific screen. here is my solution. Now forget about the re-render (performance) issue.

       <Tab.Screen
        initialParams={{
            onRemovePress: () => {
              props.setShowPopup(true)
            }
          }}
        name="Followers"
        component={Followers}
        options={{
          tabBarLabel: ({ focused, color }) => {
            return (
              <Text style={{ color: focused ? light.tintColor : light.black, marginBottom: 10 }}>{`${props.numOfFollowers} Followers`}</Text>
            )
          }
        }}
      />
<Tab.Screen
   name='tabName'
   children={()=>{
    return(
      <CustomComponent prop={yourProp} />
    )
   }}
  />

Was looking into this first time today, and found it very helpful just wanted to give small update, for @react-navigation/bottom-tabs, v^5.11.10, you need to make sure you are no longer passing in the component prop in Tab.screen and make sure the anonymous function in children, returns an element/component.

In case you are using ScreenMap to render screens you could do it like this:

_renderScene = SceneMap({
    first: () => <MyEvents {...this.props} date={this.state.date} />,
    second: () => <F4FEvents {...this.props} date={this.state.date} />,
});

you can use the following

<Tab.Screen name="Favourite" component={() => <RecipeList CategoryId={0}></RecipeList>}/>

You may gate a warning loss of current state due to re-render the component. but the props will work. If you want to copy current state props then you can use {...props}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM