【问题标题】:How to pass props to Screen component with a tab navigator?如何使用选项卡导航器将道具传递给 Screen 组件?
【发布时间】:2020-06-11 19:39:39
【问题描述】:

这是我在 StackOverflow 上的第一篇文章,如果我没有遵循正确的格式,敬请见谅。

我正在使用 tab navigator from React Navigation v 5.x 构建我的第一个应用程序,并且在将道具从一个屏幕传递到另一个屏幕时遇到了一个大问题

我想要实现的是:

  1. 在我的一个屏幕中更改数据列表。
  2. 这些更改是否会影响另一个屏幕上发生的事情。

我尝试过this(我未能设置要传递的道具)、this(已弃用的 react-navigation 版本)和this(也是旧版本的 react-navigation)。

和 Redux,但当前版本的反应导航没有可用的示例。

我已经走到了尽头,真的需要一步一步来了解如何实现这一目标。 这是我想要做的粗略草图:

我的想法是通过回调将父状态作为道具发送下来,但是我找不到通过最新版本的反应导航中的屏幕组件发送道具的方法......

这是我的导航设置:

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>
        )
    }
}

我读过this,但这对我来说毫无意义。这如何适合组件树?什么去哪里?请帮忙!

【问题讨论】:

标签: reactjs react-native react-redux parameter-passing react-props


【解决方案1】:

你可以使用属性 'children' 来传递一个类似 jsx 的元素类型,而不是属性 'component',这是 react-native 推荐的。

通过这种方式,您可以将 props 传递给组件示例:

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

必须使用 '()=>',因为子属性需要一个返回 jsx 元素的函数,它是函数式的。

【讨论】:

  • 为了获得导航道具,建议您这样使用&lt;Tab.Screen name="home" children={props =&gt; &lt;Component user={user} {...props} /&gt;} /&gt;
  • 作为开始开发 React 的 iOS 开发者,这是我讨厌 react-native 的众多原因之一 :(
  • 这是寻找解决方案数天后的答案。
【解决方案2】:

查看代码cmets中的答案。

<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.
/>

看起来您正在为屏幕“AdminTab”的“组件”道具传递内联函数(例如component={() =&gt; &lt;SomeComponent /&gt;})。传递内联函数将导致组件状态在重新渲染时丢失并导致性能问题,因为它在每次渲染时都重新创建。您可以将函数作为子函数传递给“屏幕”以实现所需的行为。

【讨论】:

  • 赞成额外的评论比较组件。谢谢!
【解决方案3】:

为了向&lt;MyTests /&gt;组件发送props,在&lt;Tab.Screen /&gt;内部:

<Tab.Screen name="My tests">
  {() => <MyTests myPropsName={myPropsValue} />}
</Tab.Screen>

【讨论】:

  • {(navigation) => }
  • 我收到一个错误,“屏幕“xxxx”的“孩子”道具的值无效。它必须是一个返回 React 元素的函数
  • 如您所见,它是一个返回 React Element 的函数。
【解决方案4】:

React Navigation 版本 5+

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

可以使用 Works 组件上的 props 访问。

【讨论】:

  • 你现在的男人,Dawg!这就是诀窍。谢谢。仅供参考,在Works 组件内部,您可以通过this.props.route.params.age 访问age(或任何initialParams)。
【解决方案5】:

我还需要向屏幕传递一个函数,以便在所有屏幕上呈现弹出窗口,但需要从特定屏幕显示弹出窗口。这是我的解决方案。现在忘记重新渲染(性能)问题。

       <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>
            )
          }
        }}
      />

【讨论】:

    【解决方案6】:
    <Tab.Navigator>
       <Tab.Screen name="Lead">
       {() => <LeadList {...this.props} />}
       </Tab.Screen>
    
       <Tab.Screen name="Opportunity">
       {() => <OpportunityList {...this.props} />}
       </Tab.Screen>
    </Tab.Navigator>
    

    【讨论】:

      【解决方案7】:

      你可以使用下面的

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

      您可能会因重新渲染组件而发出当前状态丢失的警告。但道具会起作用。 如果要复制当前状态道具,则可以使用 {...props}

      【讨论】:

      • 传递内联函数将导致组件状态在重新渲染时丢失并导致性能问题,因为它在每次渲染时都会重新创建。您可以将该函数作为子函数传递给“屏幕”以实现所需的行为。
      【解决方案8】:
      <Tab.Screen
         name='tabName'
         children={()=>{
          return(
            <CustomComponent prop={yourProp} />
          )
         }}
        />
      

      今天第一次研究这个,发现它非常有帮助,只是想提供一个小的更新,对于@react-navigation/bottom-tabs,v^5.11.10,你需要确保你不再传入Tab.screen 中的组件属性,并确保子项中的匿名函数返回一个元素/组件。

      【讨论】:

      • 您的代码 sn-p 不可运行,请编辑它以仅显示为代码格式文本
      【解决方案9】:

      如果您使用 ScreenMap 来渲染屏幕,您可以这样做:

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

      【讨论】:

        猜你喜欢
        • 2021-04-13
        • 1970-01-01
        • 2018-08-19
        • 2021-03-27
        • 1970-01-01
        • 2018-10-30
        • 2020-07-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多