Home > Back-end >  add styles to child components using props.children, react
add styles to child components using props.children, react

Time:07-26

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}
  • Related