如何使用选项卡导航器将道具传递给 Screen 组件?

Posted

技术标签:

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

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

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

我想要实现的是:

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

我尝试过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,但这对我来说毫无意义。这如何适合组件树?什么去哪里?请帮忙!

【问题讨论】:

你运气好吗?我在同一条船上,不知道该怎么做。 这能回答你的问题吗? React Native - pass props from One screen to another screen (using tab navigator to navigate) @CaseSilva 看看这是否对您有帮助***.com/a/61112784/11725995 不是真的,因为我需要创建使用主 App 组件中数据的组件,我认为不应该在那里显式创建它。需要状态值的组件还需要与其父组件通信,该父组件位于堆栈/选项卡导航树的下方。 我遇到了非常相似的情况,最终使用了 React 的 Context API。检查这是否适合您的需求:***.com/a/61196113/6581190 【参考方案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 />,
);

【讨论】:

以上是关于如何使用选项卡导航器将道具传递给 Screen 组件?的主要内容,如果未能解决你的问题,请参考以下文章

如何将道具传递给 React Navigation 导航器中的组件?

我如何将道具传递给ListHeaderComponent?

如何将 BootstrapVue 中的道具传递给路由器链接

将“导航”和“道具”传递给子组件

反应导航:如何在打字稿中使用 NavigationStackScreenComponent 类型传递 redux 道具

在Vuetify和Vue JS中将道具传递给父母