将反应组件作为道具传递

Posted

技术标签:

【中文标题】将反应组件作为道具传递【英文标题】:Pass react component as props 【发布时间】:2017-01-31 20:05:06 【问题描述】:

假设我有:

import Statement from './Statement';
import SchoolDetails from './SchoolDetails';
import AuthorizedStaff from './AuthorizedStaff';

const MultiTab = () => (
  <Tabs initialIndex=1 justify="start" className="tablisty">
    <Tab title="First Title" className="home">
      <Statement />
    </Tab>
    <Tab title="Second Title" className="check">
      <SchoolDetails />
    </Tab>
    <Tab title="Third Title" className="staff">
      <AuthorizedStaff />
    </Tab>
  </Tabs>
);

在 Tabs 组件中,this.props 具有属性

+Children[3]
className="tablist"
justify="start"

Children[0] (this.props.children) 看起来像

$$typeof:
Symbol(react.element)
_owner:ReactCompositeComponentWrapper
_self:null
_shadowChildren:Object
_source:null
_store:Object
key:null
props:Object
ref:null
type: Tab(props, context)
__proto__
Object

Children[0].props 看起来像

+Children (one element)
className="home"
title="first title"

最后 Children 对象看起来像(这是我想要传递的):

$$typeof:Symbol(react.element)
_owner:ReactCompositeComponentWrapper
_self:null
_shadowChildren:undefined
_source:null
_store:
key:null
props:Object
__proto__:Object
**type: function Statement()**
ref:null

问题是这样的,如果我这样重写 MultiTab

<Tabs initialIndex=1 justify="start" className="tablisty">
  <Tab title="First Title" className="home" pass=Statement />
  <Tab title="Second Title" className="check" pass=SchoolDetails />
  <Tab title="Third Title" className="staff" pass=AuthorizedStaff />
</Tabs>;

标签组件内部

this.props.children 看起来和上面一样。

children[0].props 看起来像

classname:"home"
**pass: function Statement()**
title: "First title"

我希望pass 属性看起来像。上面只是打印了 Statement 函数。

$$typeof:Symbol(react.element)
_owner:ReactCompositeComponentWrapper
_self:null
_shadowChildren:undefined
_source:null
_store:
key:null
props:Object
__proto__:Object
**type: function Statement()**
ref:null

这是一个奇怪的问题,但说来话长,我正在使用一个库,这就是它的归结。

【问题讨论】:

为什么要将组件作为道具传递?什么时候可以导入 @AatifBandey 因为他传递了不同的组件?您将如何使用导入来解决这个问题?传递字符串并进行相等性检查?这没有任何意义。 这能回答你的问题吗? How to pass in a react component into another react component to transclude the first component's content? 【参考方案1】:

使用this.props.children 是将实例化组件传递给反应组件的惯用方式

const Label = props => <span>props.children</span>
const Tab = props => <div>props.children</div>
const Page = () => <Tab><Label>Foo</Label></Tab>

当您直接将组件作为参数传递时,您将未实例化并通过从道具中检索它来实例化它。这是传递组件类的惯用方式,然后将由组件沿树向下实例化(例如,如果组件在标签上使用自定义样式,但它想让消费者选择该标签是 div 还是span):

const Label = props => <span>props.children</span>
const Button = props => 
    const Inner = props.inner; // Note: variable name _must_ start with a capital letter 
    return <button><Inner>Foo</Inner></button>

const Page = () => <Button inner=Label/>

如果你想做的是传递一个类似于孩子的参数作​​为道具,你可以这样做:

const Label = props => <span>props.content</span>
const Tab = props => <div>props.content</div>
const Page = () => <Tab content=<Label content='Foo' /> />

毕竟,React 中的属性只是常规的 javascript 对象属性,可以保存任何值——无论是字符串、函数还是复杂对象。

【讨论】:

我知道你提供了很多很好的箭头函数示例。但是你介意展示一下如果代码被分成不同的文件会是什么样子吗?我对如何使用classexport 有点困惑 只需使用export const Foo = ...,然后在其他地方使用import Foo from "./foo" 提示:确保Inner 不是inner。否则不起作用 基本上传递一个像&lt;Com a="5" /&gt;这样的组件只是把它变成一个箭头函数:() =&gt; &lt;Com a="5" /&gt;【参考方案2】:

如已接受的答案中所述 - 您可以使用特殊的 props.children 属性。但是 - 您可以根据标题请求将组件作为道具传递。我认为这有时更干净,因为您可能想要传递几个组件并将它们呈现在不同的位置。以下是反应文档,其中包含如何操作的示例:

https://reactjs.org/docs/composition-vs-inheritance.html

确保您实际上传递的是一个组件而不是一个对象(这最初让我感到困惑)。

代码就是这样:

const Parent = () =>  
  return (
    <Child  componentToPassDown=<SomeComp />  />
  )


const Child = ( componentToPassDown ) =>  
  return (
    <>
     componentToPassDown  
    </>
  )

【讨论】:

如果孩子有一个道具。我如何在父母中访问它。 @NicoleZ - 基本思想是扭转问题。即,在父级中创建变量并将其作为道具传递给子级。如果您希望孩子更改变量,那么您需要在父项中创建一个函数来执行此操作,并将其作为另一个道具传递。 如何在 chidl 方法中给 componentToPassDown 提供道具? @HadiPawar 把道具传下来:&lt;Child componentToPassDown=&lt;SomeComp yeet=true /&gt; /&gt;【参考方案3】:

在我的例子中,我将一些组件(type_of_FunctionComponent)堆叠成一个对象,例如:

[
 ...,one : ComponentOne,
 ...,two : ComponentTwo
]

然后我将它传递给一个动画滑块,在幻灯片组件中,我做了:

const PassedComponent:FunctionComponent<any> = Passed;

然后使用它:

<PassedComponent ...custom_props />

【讨论】:

【参考方案4】:

我必须有条件地渲染组件,所以以下对我有帮助:

const Parent = () =>  
  return (
    <Child  componentToPassDown=<SomeComp />  />
  )


const Child = ( componentToPassDown ) =>  
  return (
    <>
     conditionToCheck ? componentToPassDown : <div>Some other code</div>
    </>
  )

【讨论】:

【参考方案5】:

如何使用 React 包中的“React.createElement(component, props)”

const showModalScrollable = (component, props) => 
 Navigation.showModal(
   component: 
     name: COMPONENT_NAMES.modalScrollable,
     passProps: 
        renderContent: (componentId) => 
          const allProps =  componentId, ...props ;

          return React.createElement(component, allProps);
    ,
  ,
,

); ;

【讨论】:

以上是关于将反应组件作为道具传递的主要内容,如果未能解决你的问题,请参考以下文章

在反应中使用css模块如何将className作为道具传递给组件

从标准 html 传递道具以反应组件

传递给子组件时道具未定义(反应钩子)

反应:作为道具的数组显示为未定义

反应不将道具传递给组件

将道具传递给动态反应组件