Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React: Mapping children of a parent component

Tags:

So I want to add certain styles to any child that's appended to a component. Let's say the parent component is called Section and children are called Cardin this case. in Section.js I am trying this: -

renderChildren = () =>{   return React.Children.map(this.props.children, (child, i)=>{     let el = React.cloneElement(child,{       style: {opacity:0.5}     })     return el   }) }  render(){   <ScrollView>        {this.renderChildren()}    </ScrollView> } 

The above approach doesn't work for me. And I would like to know why. Also is there a way where I could map across the children and wrap them in a new component? Something like this;

this.props.children.map(Child => <Wrapper> <Child/> </Wrapper> ) 
like image 407
Anish K. Avatar asked Mar 26 '18 17:03

Anish K.


People also ask

How do you pass property from parent to child in React?

To pass data from a child component to its parent, we can call a parent function from the child component with arguments. The parent function can be passed down to the child as a prop, and the function arguments are the data that the parent will receive.

Can React components have children?

React Components and Children In React, a component can have one, many, or no children.


2 Answers

To wrap your children into a wrapper just put the call to React.Children.map into the wrapper component:

const OpaqueWrapper = ({ children }) => (     // check that children is defined      // if you do not want your wrapper to be rendered empty     children && (         <Wrapper>             {React.Children.map(children, child => (                 React.cloneElement(child, {style: {...child.props.style, opacity: 0.5}})             ))}         </Wrapper>     ) ); 

Also note that you have to merge the styles provided to the original child with the styles injected or you will lose the ability to style the children at all.

See this codesandbox for a working example.

As to why it did not work in your code: Are you sure that your <Card> component does handle the style prop correctly, i.e. applying it to it's children?

EDIT:

The sloution wraps all children components in a single wrapper, but I would like to wrap each child with the applied wrapper , as shown in my question.

The just move the wrapper into React.Children.map:

const OpaqueWrapper = ({ children }) => (             React.Children.map(children, child => (        <Wrapper>            {React.cloneElement(child, {style: {...child.props.style, opacity: 0.5}})}        </Wrapper>     ))) ); 
like image 152
trixn Avatar answered Feb 02 '23 16:02

trixn


I think this solution is the simplest for wrap every child. When the children are rendered, you receive an instance of the component, not the component function. And you just need to wrap the instance into the wrapper component as shown below.

this.props.children.map(child => <Wrapper>{child}</Wrapper> ) 

For TypeScript:

React.Children.map(props.children, child => {   return <Wrapper>{child}</Wrapper> }) 
like image 29
Igor Stetsiura Avatar answered Feb 02 '23 15:02

Igor Stetsiura