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

时间:2017-02-03 04:38:47

标签: javascript reactjs react-jsx

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

例如:

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

问题:

  1. 使用ReactJS是否可行/可行?

  2. 如果对1的回答是肯定的,那么当这个结构可以使用/好处时会有什么实际情况(一个例子有助于理解)

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

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

    提前致谢。

2 个答案:

答案 0 :(得分:1)

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

当你拥有通用和可重用的组件时,这种情况很有用。让我们说ShoppingApp有10个Products,每个Products都有ProductDetails,在这种情况下,你可以使用ProductsProductDetail组件10次,通过使用循环,您可以创建10 ProductsProductDetail组件。由于所有Products都具有相同的属性,如Name,Price等,因此您可以轻松编写可重用的组件,并将组件内的数据作为道具传递。

像这样:

_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>

但是在场景中就像你可以使它更通用一样,因为ProductDetailProduct的属性所以不是像这样使用你可以直接使用ProductDetail 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的孩子传递。

希望它能帮助你理解:)

答案 1 :(得分:1)

如果我正确理解了您的问题,那么您正在寻找像React(来自文档)传递给每个组件的特殊children道具

当您不知道某个组件的子项将提前完成时,这是特别适用的。

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

 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>
     )
   }
 }

在实际场景中,如果您希望将ProductDetail组件嵌套在Products组件中,因为您希望Products以某种方式将一些道具传递给每个ProductDetail 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> ) } } 组件它包含,您可以使用React.Children(docs)提供的各种记录良好的实用程序

一个实际的例子如下 -

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

所以你的render语句如下所示:

ProductDetails

在这种情况下,所有内部categories子项都会将道具groceries设置为HelloWorld。但是,内部categories组件不会传递ProductDetails道具,因为它不属于{{1}}类型。

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