I am interested in doing something like below in my React Applications i.e. create my Custom Components and nest them in the return statement:
eg:
render(){
return(
<ShoppingApp>
<Products>
<ProductDetail productID={product_id} />
</Products>
</ShoppingApp>
);
}
Questions:
Is the above possible / feasible using ReactJS ?
If the answer to 1 is yes, then what will be the practical scenario when this structure can be used / benefits (an example would help in understanding)
How to implement this kind of nesting with custom components?
PS: I already know the syntax where we can include a component in JSX inside div, table, . . . , but the question here is how to implement nesting Custom components inside each other in a hierarchy (like described above).
Thanks in advance.
If I understand your question correctly, you are looking for something like the special children prop that is passed to every component by React (from the docs)
This is specifically applicable when you don't know the what the children to a component will be ahead of time.
In your case, this could be implemented roughly as follows -
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>
)
}
}
In a real-world scenario, if you want to nest the ProductDetail component inside the Products component because you want Products in some way to pass some prop to each ProductDetail it contains, you can use the various well documented utilities provided by React.Children (docs)
So a practical example would be as follows -
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>
)
}
}
So your render statement would look like as follows:
<Products category='groceries'>
<ProductDetails id='1' />
<ProductDetails id='2' />
<HelloWorld />
</Products>
And in this case, all the inner ProductDetails children will have a prop categories set to groceries. However, the inner HelloWorld component will not be passed the categories prop because it's not of type ProductDetails.
Another practical application where this paradigm is used is if you want the parent custom component to passing inline styles to all or some of it's children, and can be very useful if, say, you are writing writing your own libraries.
Yes above structure is possible. Here you are passing ProductDetail as the children of Products component, then passing Products as the children of ShoppingApp.
This kind of scenario is helpful when u have the generic and reusable components. Lets say ShoppingApp have 10 Products and each Products have the ProductDetails, in that case u can use the Products and ProductDetailcomponents 10 times, by using loop you can create the 10 Products and ProductDetail component. Since all the Products will have same properties like Name, Price etc, you can easily write a reusable components and just pass the data inside the components as props.
Like this:
_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>
But in scenario Like you can make it more general, since ProductDetail is the property of Product so instead of using like this u can directly use the ProductDetail inside Product like this:
_createProductList(){
let products = this.state.products;
return products.map((product,i)=>{
return <Products key={i} data={product}/>
})
}
<ShoppingApp>
{this._createProductList()}
</ShoppingApp>
And inside Products Use ProductDetails in render. No need to pass it as the children of Product.
Hope it will help you to understand :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With