ReactJs - 如何在一个组件中使用多个子组件

Posted

技术标签:

【中文标题】ReactJs - 如何在一个组件中使用多个子组件【英文标题】:ReactJs - how to use multiple children in a component 【发布时间】:2020-03-06 23:28:59 【问题描述】:

我以我对 ReactJs 非常陌生,并且可能试图解决一些非常基本的事情作为开头。

我有一段带有自定义 html 的代码:

示例组件

const Sample = ( title, children ) => 
    return (
          <div class="panel">
              <div class="title">
                 title
              </div>
              <div class="body">
                 children
              </div>
           </div>    
     );
;

附带问题 - 上面的正确名称是什么?一个片段?它看起来不是一个“组件”,而只是学习 React 的命名约定

利用组件

export default class ExampleComponent extends Component 
    render() 
        return <div class="page-body">
            <div class="row">
                <h1> Page 1 </h1>
                <Sample title=<h1>Some title!</h1>>
                   <p>This is my sample body!</p>
                </Sample>
            </div>
        </div>
    


您可以看到“Sample”元素的内容自动作为 children 属性,但要设置标题,我必须明确设置“title”属性。理想情况下,我想做的是类似于以下内容:

使用示例组件的理想方式

export default class ExampleComponent extends Component 
    render() 
        return <div class="page-body">
            <div class="row">
                <h1> Page 1 </h1>
                <Sample title="Some title!">
                   <Sample.Title>
                       <h1>This is my new way to do a title</h1>
                   </Sample.Title>
                   <Sample.Body>
                       <p>This is my sample body!</p>
                   </Sample.Body>
                </Sample>
            </div>
        </div>
    

我以前在其他人创建的组件中使用过这种方法,但现在想自己做,发现很难找到一个简单的例子来做到这一点。

提前感谢您的任何指点!

【问题讨论】:

以上是一个组件。一个片段是&lt;&gt;/* content */&lt;/&gt; 在你想要的输出中,你确定要通过title="Some Title!"吗?这似乎违背了以下代码的目的;) 【参考方案1】:

我认为你想要的叫做 JSX 命名空间?无论哪种方式,您都可以实例化 Sample,然后添加更多组件作为 Sample 的属性(将其视为对象):

import React from "react"

const Sample = ( children ) => (
  <div className="panel">
      children
  </div>    
)


Sample.Title = (props) => <div className="title">props.children</div>
Sample.Body = (props) => <div className="body">props.children</div>

export default Sample

注意:React 使用 className 而不是 class,因为我们使用的是 JSX。

【讨论】:

这非常适合我的场景!谢谢大家的建议!! :-D @RobMcCabe 不用担心。如果您在反应方面需要更多帮助或有不明白的地方,请随时询问? 100 + 喜欢您的回答。【参考方案2】:

Children utils 套装对您的场景很有帮助。

import  Children  from 'react'

const Sample = ( title, children ) => 
  let _body, _title

  Children.forEach(children, child => 
    if (child.type === SampleTitle) 
      return _title = child
    

    if (child.type === SampleBody) 
      return _body = child
    
  )

  if (!_title) _title = <div className='title'>title</div>
  if (!_body) _body = <div className='title'>children</div>

  return (
    <div className='panel'>
      _title
      _body
    </div>
  )


const SampleTitle = ( children ) => <div className='title'>children</div>
const SampleBody = ( children ) => <div className='body'>children</div>

Sampe.Title = SampleTitle
Sample.Body = SampleBody

现在您可以通过多种方式使用 Sample:

<Sample title="my title">
  <div>my body</div>
</Sample>

<Sample title="my title">
  <Sample.Body>my body</Sample.Body>
</Sample>

<Sample title="my fallback title">
  <Sample.Title>my overriding title</Sample.Title>
  <Sample.Body>my body</Sample.Body>
</Sample>

【讨论】:

【参考方案3】:

在这种情况下,您只需将相关容器提取到它们自己的组件中:

const Sample = (children ) => (
    <div className="panel">children</div>    
);

const Title = (children) => (
    <div className="title">children</div>
);

const Body = (children) => (
    <div className="body">children</div>
);

Sample.Title = Title;
Sample.Body = Body;

另请注意,css 类的正确 prop 是 className

【讨论】:

以上是关于ReactJs - 如何在一个组件中使用多个子组件的主要内容,如果未能解决你的问题,请参考以下文章

如何在 reactjs 中使用 onclick 事件渲染子组件?

如何在状态更改(父)reactjs时重新渲染子组件

如何在 Reactjs 中将数据从子组件传递到父组件? [复制]

ReactJS中从父组件调用子函数时如何在子组件中设置状态

ReactJs:如何创建一个包装器组件,该组件在单击时会执行某些代码并呈现子组件?

ReactJS:如何将子组件传递给它的祖先?