【问题标题】: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

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

【问题讨论】:

标签: javascript reactjs


【解决方案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);
          },
        },
      },
      

      }); };

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-07-28
        • 2017-08-17
        • 1970-01-01
        • 2017-07-19
        • 2019-07-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多