Propagate style props to React children and apply them to a CSS file

So with React if you pass props that are the same name, it only select the one that was passed last. So with your two style props, it only would pass the last one. However, it probably isn’t the best idea to use the name style anyway, since it isn’t descriptive and also mirrors the actual HTML style attribute.

Give the two different styles unique names, in the App.js file:

<div className="App">
  <Dropdown
    inputName="viola"
    list={[
      { yard_id: "1", yard_name: "Yard 1" },
      { yard_id: "2", yard_name: "Yard 2" }
    ]}
    // this style is for  className="select-box-current"
    currentStyles={{ border: "1px solid #D4D4D4" }}
    // this style is for className="select-box-list"
    listStyles={{
      opacity: 1,
      display: "inherit",
      animationName: "none",
      cursor: "pointer"
    }}
  />
</div>

Now we need to pass those two props through your component tree, the next file is the Dropdown.js file.

Before I get to passing the props, I want to comment about something that is wrong, that isn’t entirely related.

export const Dropdown = ({ list, ...others }) => {
  const copiedProps = {};
  Object.keys(others).forEach((key) => {
    // these are the props that need to get thru:
    if ("style" === key || "className" === key) {
      copiedProps[key] = others[key];
    }
  });

  ...

The copying of props, isn’t necessary and the way that it is done is actually detrimental. If you want to specifically target a value in the incoming props, you can access it directly (ex props.myProp or in this case other.style) or destructuring assignment.

Since you are wanting to only pass the style (now listStyles and currentStyles) and the className I chose to assign them to a variable using the destructuring assignment.

export const Dropdown = ({
  list,
  currentStyles,
  listStyles,
  className,
  ...others
}) => { ... }

Now that we have those props, we want to pass it into your DropdownView which contains the actual elements you’re wanting to target.

<DropdownView
  dropdownItems={dropdownItems}
  activeItem={activeItem}
  hover={hover}
  setActiveItem={(activeItem) => {
    setActiveItem(activeItem);
  }}
  onMouseOver={(hover) => onMouseOver(hover)}
  toggleList={() => toggleList(!hideList)}
  hideList={hideList}
  className={className}
  currentStyles={currentStyles}
  listStyles={listStyles}
/>

Okay, now we have the styles and classname where we want them. All you have to do is get the props like we did above, and then set them on the elements.

<div
  className="select-box-current"
  tabIndex="0"
  autoFocus={true}
  onClick={() => toggleList()}
  style={currentStyles}
>...</div>

I forked the sandbox to include a working example. But node that I didn’t set the use the className prop in the DropdowView since it wasn’t clear what element would have that.

https://codesandbox.io/s/hardcore-sun-yyx0g?file=/src/DropdownView.jsx

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top