创建自定义组件并嵌套它们

Creating Custom Components and Nesting them

我有兴趣在我的 React 应用程序中做类似下面的事情,即创建我的自定义组件并将它们嵌套在 return 语句中:

例如:

render(){
    return(
        <ShoppingApp>
            <Products>
                <ProductDetail productID={product_id} />
            </Products>
        </ShoppingApp>
    );
}

问题:

  1. 以上使用 ReactJS 是否可能/可行?

  2. 如果1的答案是肯定的,那么这个结构可以使用/受益的实际场景是什么(举个例子有助于理解)

  3. 如何用自定义组件实现这种嵌套?

PS:我已经知道我们可以在 div、table 中包含 JSX 组件的语法。 . . ,但这里的问题是如何在层次结构中实现彼此嵌套的自定义组件(如上所述)。

提前致谢。

是的,以上结构是可能的。在这里,您将 ProductDetail 作为 Products 组件的子级传递,然后将 Products 作为 ShoppingApp.

的子级传递

当您拥有通用且可重用的组件时,这种情况会很有帮助。假设 ShoppingApp 有 10 个 Products,每个 ProductsProductDetails,在这种情况下,您可以使用 ProductsProductDetail 组件 10 次,通过使用循环,您可以创建 10 ProductsProductDetail 组件。由于所有 Products 都将具有相同的属性,如名称、价格等,您可以轻松编写可重用的组件,并将组件内的数据作为道具传递。

像这样:

_createProductList(){
    let products = this.state.products;
    return products.map((product,i)=>{
        return <Products key={i} data={product}>
                   <ProductDetail data={product}>
                   </ProductDetail>
               </Products>
    })
}

<ShoppingApp>
    {this._createProductList()}
</ShoppingApp>

但是在场景 Like 你可以让它更通用,因为 ProductDetailProduct 的 属性 所以你可以直接使用 [=12= 而不是像这样使用] 在 Product 里面像这样:

_createProductList(){
    let products = this.state.products;
    return products.map((product,i)=>{
        return <Products key={i} data={product}/>
    })
}

<ShoppingApp>
    {this._createProductList()}
</ShoppingApp>

并在 Products 内使用 ProductDetails 进行渲染。无需将其作为 Product.

的子级传递

希望它能帮助你理解:)

如果我正确理解你的问题,你正在寻找类似特殊的 children prop 的东西,它由 React 传递给每个组件(来自文档)

当您事先不知道组件的子组件是什么时,这尤其适用。

在你的情况下,这可以大致如下实现 -

 class Products extends React.Component {
   render() {
     /* this.props.children here will be an array of all 
      * the children which can be custom components
      * enclosed within the <Products> component 
      * when it is rendered 
      */
     return (
       <div className='products'> 
         {this.props.children}
       </div>
     )
   }
 }

在 real-world 场景中,如果您想将 ProductDetail 组件嵌套在 Products 组件中,因为您希望 Products 以某种方式将一些 prop 传递给它包含的每个 ProductDetail,您可以使用 React.Children (docs)

提供的各种有据可查的实用程序

所以一个实际的例子如下 -

 class Products extends React.Component {
   getTransformedChildren() {
     return React.Children.map(this.props.children, child => {
       // if child is of type ProductsDetail, clone it so you can 
       // pass your own prop to it else return the child
       const newChild = (child.type === ProductsDetail) ? 
         React.cloneElement(child, { category: this.props.category }) :
         child
       return newChild
   }
   render() {
     return (
       <div className='products'> 
         {this.getTransformedChildren()}
       </div>
     )
   }
 }

因此您的渲染语句如下所示:

<Products category='groceries'>
   <ProductDetails id='1' />
   <ProductDetails id='2' />
   <HelloWorld />
</Products>

在这种情况下,所有内部 ProductDetails 子级都将属性 categories 设置为 groceries。但是,内部 HelloWorld 组件不会传递 categories 属性,因为它不是 ProductDetails.

类型

另一个使用此范例的实际应用是,如果您希望父自定义组件将内联样式传递给它的所有或部分子组件,并且如果您正在编写自己的库,这将非常有用。