score:289
props.children
isn't the actual children; It is the descriptor of the children. So you don't have actually anything to change; you can't change any props, or edit any functionality; you can only read from it. If you need to make any modifications you have to create new elements using React.CloneElement
.
An example:
main render function of a component such as App.js
:
render() {
return(
<Paragraph>
<Sentence>First</Sentence>
<Sentence>Second</Sentence>
<Sentence>Third</Sentence>
</Paragraph>
)
}
now let's say you need to add an onClick
to each child of Paragraph
; so in your Paragraph.js
you can do:
render() {
return (
<div>
{React.Children.map(this.props.children, child => {
return React.cloneElement(child, {
onClick: this.props.onClick })
})}
</div>
)
}
then simply you can do this:
render() {
return(
<Paragraph onClick={this.onClick}>
<Sentence>First</Sentence>
<Sentence>Second</Sentence>
<Sentence>Third</Sentence>
</Paragraph>
)
}
Note: the React.Children.map
function will only see the top level elements, it does not see any of the things that those elements render; meaning that you are providing the direct props to children (here the <Sentence />
elements). If you need the props to be passed down further, let's say you will have a <div></div>
inside one of the <Sentence />
elements that wants to use the onClick
prop then in that case you can use the Context API to do it. Make the Paragraph
the provider and the Sentence
elements as consumer.
score:29
In fact, React.cloneElement
is not strictly associated with this.props.children
.
It's useful whenever you need to clone react elements(PropTypes.element
) to add/override props, without wanting the parent to have knowledge about those component internals(e.g, attaching event handlers or assigning key
/ref
attributes).
Also react elements are immutable.
React.cloneElement( element, [props], [...children] ) is almost equivalent to:
<element.type {...element.props} {...props}>{children}</element.type>
However, the children
prop in React is especially used for containment (aka composition), pairing with React.Children
API and React.cloneElement
, component that uses props.children can handle more logic(e.g., state transitions, events, DOM measurements etc) internally while yielding the rendering part to wherever it's used, React Router <switch/>
or compound component <select/>
are some great examples.
One last thing that worth mentioning is that react elements are not restricted to props.children.
function SplitPane(props) {
return (
<div className="SplitPane">
<div className="SplitPane-left">
{props.left}
</div>
<div className="SplitPane-right">
{props.right}
</div>
</div>
);
}
function App() {
return (
<SplitPane
left={
<Contacts />
}
right={
<Chat />
} />
);
}
They can be whatever props that makes sense, the key was to define a good contract for the component, so that the consumers of it can be decoupled from the underlying implementation details, regardless whether it's using React.Children
, React.cloneElement
, or even React.createContext
.
score:75
Edit:
Look at Vennesa's answer instead, which is a better explanation.
Original:
First of all, the React.cloneElement
example only works if your child is a single React element.
For almost everything {this.props.children}
is the one you want.
Cloning is useful in some more advanced scenarios, where a parent sends in an element and the child component needs to change some props on that element or add things like ref for accessing the actual DOM element.
In the example above, the parent which gives the child does not know about the key requirement for the component, therefore it creates a copy of the element it is given and adds a key based on some unique identifier in the object. For more info on what key does: https://facebook.github.io/react/docs/multiple-components.html
Source: stackoverflow.com
Related Query
- when we enter the username in login page, Home page should display Welcome {username} , how to show this using react js
- You should not use Route or withRouter() outside a Router when using react-router 4 and styled-component in react
- React context is undefined when the children are rendered using this.props.children
- how to pass props to the route when using react router <Link>
- How can I spread props to a React component that uses exact props when using Flow?
- How should unsubscribe be handled in a react component when using redux?
- when should I pass 'className' props to react component?
- Should the action or store be responsible for transforming data when using React + Flux?
- this keyword value when using React event handlers
- Should not have to disable eslint when using with react
- When Using Redux Saga with React Get This Error .. Uncaught TypeError: getPosts is not a function
- React this is undefined when using setState
- when i increment the counter it increases by 2 not one. i am using react context for this
- Why does React re-renders children when props does not change?
- Passing both match param and props into react component when using routing
- react redux props undefined on event listener when using mapDispatchToProps
- With React + TypeScript, how do I avoid typecasting when using optional props with defaults with strictNullChecks enabled?
- Props mix when using the same component multiple times on a page in React
- Setting React component initial props when using npm & browserify
- I have this `div` on my home page and want it to move with me when I scroll, I am using react for the website btw
- How to avoid re-renders in React when using conditional Render and children node prop
- React - Rendered item is not updating after initial render. When props change, should select different data
- How to preserve children when using cloneElement
- Bind this when using method decorators in React
- Props is always undefined when using <Link> with react router, on every page
- Error Coming when passing props from one component to another and vice - versa in react using typescript
- How to get parent props in child component when using styled component in react
- React adds array when using props
- i am facing react must be in scope when using jsx this tyoe of error...?
- React - how to add boolean field on props when using map(), given that the field will be changing
More Query from same tag
- Why is React redirect not working for me?
- Redirect to login page using react-router v4
- Typescript React useCallback eslint force typed arguments
- Handle multiple Checkboxed in a State:Array. How to?
- Components overlapping each other in React
- Creating a smooth progress bar in React
- How to separate a custom library in vendor.js and load it as a separate file specifically on click of link
- Font Size React native
- Redux - Calling storeAPI.disapatch(action) inside middleware causes 'too much recursion'
- TypeError : "onChange is not a function"
- How to create reusable custom modal component in React?
- How can i create a separate chunk for each component?
- React useSelector and getState returning different values in useEffect
- Node Version Trouble deploying React app onto GCP
- getServerSideProps in _app.tsx in Next.js
- ReactJS - setState working in a weird way
- how to store a function in React
- history.push is changing url but not rendering component in react
- React props change unexpectedly when a variable initialized as props changes
- React: Remove certain html elements from string and normalize
- React: why do you have to bind this method?
- How to render a d3.js map inside of a React component?
- setTimeout in Jest/Enzyme Tests
- Simulate a click on span tag in enzyme
- Google tag manager not sending analytics request after route changes
- copy array item and put in position-dependent by property value?
- Removing all componentWillMount from my project, what is the replacement if my child components depend on an api response
- Could not display not found information using conditional syntax inside jsx
- How to use one Laravel instance for two React projects
- Disallow MouseEvent with ESLint (Typescript)