Home > Back-end >  How to send a usestate through props with interface in TypeScrips and react?
How to send a usestate through props with interface in TypeScrips and react?

Time:09-30

I'm trying to make a light / dark theme . And I have 2 components. The first component is the one below. I succeeded to make a boolean to change my style in my component. It was good so far :

export interface  Props{

  theme:boolean;

}

const Theme: FC<Props> = ({theme}) => {
  const [light,setLightMode]=useState(false);
  return (
    <div>
      <div className="card__theme">
        <div className={light ? "card__light" : "card__light--active"}>Light</div>
        <Switch inputProps={{ "aria-label": "controlled" }} onChange={()=>setLightMode(!light)}/>
        <div className={ light ? "card__Dark" : "card__Dark--active"}>Dark</div>
      </div>
    </div>
  );
};

What I do right now is to use this component in my Home page where I want to do the same thing. I want to change the style of my components , making 2 className like the code above with a boolean state. The problem that I'm facing is that I can't make another function onChange={} in my home component. First I don't send in interface a function . I want my const [light,setLightMode]=useState(false); and my function onChange={()=>setLightMode(!light)} when I switch the button to work in my Home component from below

const Home: FC = () => {
  const percentage = 91;
  const [dark,setDark] = useState(false);

  return (
    <div>2
      <div className="Container-body">
        <div className="card">
          <div className={dark ? "card__theme" : "card__theme--active"}>
            <Theme theme={dark} onChange={()=>{setDark(!dark)}}/>
          </div>

So to make it sort. I want to use just the light, setlightTheme boolean state from my Theme component in my Home component . I don't know how I can send this with props in TypeScript...

Here is a print with my code : enter link description here

CodePudding user response:

I'm not sure if I understand correctly, but I think your goal is to pass the onChange function to the Theme component from the parent component. If so, I hope this snippet can help you. Basically I added the onChange parameter in the interface as a function. I also renamed the theme parameter to dark. To make the two components work together, I removed the useState in the Theme component and used the dark variable (taken from the parent component) to manage the styles.

export interface Props {
  dark: boolean;
  onChange?: () => void;
}

const Theme: FC<Props> = ({ dark, onChange }) => {
  return (
    <div>
      <div className="card__theme">
        <div className={dark ? 'card__light' : 'card__light--active'}>
          Light
        </div>
        <Switch
          inputProps={{ 'aria-label': 'controlled' }}
          onChange={onChange}
        />
        <div className={!dark ? 'card__Dark' : 'card__Dark--active'}>Dark</div>
      </div>
    </div>
  );
};

CodePudding user response:

So if I understand correctly you just want to provide an option for switching light and dark mode. From an architectural point of view you don't want to do this on a component-level since multiple component might need to change.

BEM Mistake

Before I address a proper solution you are currently making a BEM mistake with this line:

 <div className={dark ? 'card__light' : 'card__light--active'}>

A modifier --modifier can only live together with an actual element card. So on a fully outputted HTML this is valid card__light card__light--active but in your example either card__light or card__light--active is being rendered.

Solution for theme switching

When it comes down to switching a dark/light theme you either want to make this value (true or false) available in a centralised state by using something like Redux or you might want to declare it on your root component (most often the <App />) and start using it from there.

I don't recommend prop drilling for this use case since it will make your code messy in the long run. This is a really nice use case for the Context API.

✅ See working example Playground.

P.s. I use Typescript for better code, you can ignore the syntax you don't know.

React documentation

The React documentation has an exact example for you see docs theme switching.

  • Related