I am trying to build a component called ViewLayout
, The purpose of this component is that when used as a wrapper it adds some styles to each child component.
For example
export default function App() {
return (
<ViewLayout>
<div className="left-nav">
<li>Home</li>
<li>Mobiles</li>
<li>Electronics</li>
</div>
<div className="logo">Logo</div>
<div className="right-nav">
<li>Cart</li>
<li>Profile</li>
</div>
</ViewLayout>
);
}
Here the ViewLayout
has 3 children div's and I want to add border: 1px solid red
to each child div.
ViewLayout
component
function ViewLayout(props) {
console.log(props.children);
return <div>{props.children}</div>;
}
export default ViewLayout;
So every time ViewLayout
is used as a wrapper it adds the styles defined to each child component, is it possible to achieve this in react?
Source code link: https://stackblitz.com/edit/react-ts-w5dwgr?file=App.tsx,ViewLayout.tsx
CodePudding user response:
Although, for this specific use-case, handling it with CSS seems like the better approach (as the other answers suggest), here is a solution for when you really have to modify the children.
Using React.Children.map
and React.cloneElement
function ViewLayout(props) {
console.log(props.children);
const updatedChildren = React.Children.map(props.children,(child, idx) =>
React.cloneElement(
child,
{ style: { ...child.props.style, border: '1px solid red' } }
)
);
return <div>{updatedChildren}</div>;
}
Updated demo at https://stackblitz.com/edit/react-ts-sc1ubn?file=App.tsx,ViewLayout.tsx
CodePudding user response:
You can simply add a className attribute in the div tag of ViewLayout component and use CSS to target the direct div children of that class.
ViewLayout Component:
function ViewLayout(props) {
console.log(props.children);
return <div>{props.children}</div>;
}
export default ViewLayout;
CSS file:
.viewlayout > div{
border: 1px solid red;
}
If you want to target every direct child then use * in css, e.g:
.viewlayout > * {
border: 1px solid red;
}
CodePudding user response:
maybe you just use css
function ViewLayout(props) {
return <div classname='ViewLayout'>{props.children}</div>;
}
.ViewLayout div{style}