简体   繁体   中英

How to make a React component reusable in terms of styling?

Consider the following input component with its own scss file:

import React from "react";
import "./InputBox.scss";

const InputBox = () => {
  return (
    <div>
      <label for="fname">First name: </label>
      <input className="input-box" type="text" id="fname" name="fname" />
    </div>
  );
};

export default InputBox;
.input-box {
  background-color: blue;
}
import React from "react";
import InputBox from "./InputBox";
export default function App() {
  return (
    <div className="App">
      <div>The blue input box</div>
      <InputBox />
      <div>The green input box</div>
      <InputBox />
    </div>
  );
}

Working example here

The functionality is okay, my question is with the styling: say I want a green input box, it doesn't seem possible with the external SCSS file. I can pass a className as a props but I feel it's a overkill. I feel my component should not contain any style, and only apply style when using it. How can I style the same component differently?

depending on the project I usually pass a variant prop which will determine the element's styling, so for example you have a default styling for an input field but you do have so different variants of the input with its own unique styling. So all you can do is pass a variant which will add a modifier block to your class name.

default classname = 'input' depending on the variant the entire class name should be something like 'input input--variant-name'

all default styling go to the 'input' class name while the variant makes the changes. I feel it isn't an overkill as it is much more organized this way and with a use of a scss and css variables together you make have a very organized project structure for your styling.

you can do it by using useRef hook,here is the live demo link: https://codesandbox.io/s/romantic-ride-j0hdp?file=/src/App.js this way you wont be requiring any css file.

I tried to pass className as a prop and it worked, code here:

const InputBox = ({ color }) => {
  return (
    <div>
      <label for="fname">First name: </label>
      <input
        className={"input-box-" + color}
        type="text"
        id="fname"
        name="fname"
      />
    </div>
  );
};
.input-box {
  &-blue {
    background-color: blue;
  }
  &-green {
    background-color: green;
  }
}
export default function App() {
  return (
    <div className="App">
      <div>The blue input box</div>
      <InputBox color={"blue"} />
      <div>The green input box</div>
      <InputBox color={"green"} />
    </div>
  );
}

I can see a few problems already:

When design a component, should I consider all possible style changes and design them as props? If yes, then every time using the component requires writing all props, which is cumbersome. If no, adding a prop requires modifying the component.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM