Search code examples
reactjstypescriptradio-buttonlabelstyled-components

How to change label's style when I change radio inputs?


I created the className "OccupancyChecked" so it would be applied to the label of the radio that is checked, but for some reason I can't make it work.

This is the style:

const Occupancy = styled.label`
  //more code

  .OccupancyChecked {
    border: 1px solid rgba(255, 255, 255, 0.24);
    background: #7f5cf1;
  }
`;

The following is the code calling the above's className. What I tried to do was: There are just two radios, so I inserted a onChange on the first radio, the result is in each label's className, where it should call "Occupancy" className in case radio is checked or blank className if otherwise. I believe this logic should work, but it isn't. I also created a sandbox so I can display the code running.

export default function App() {
  const [occupancyChecked, setOccupancyChecked] = useState(0);

  function changeOccupancyChecked() {
    occupancyChecked === 0 ? setOccupancyChecked(1) : setOccupancyChecked(0);
    return;
  }

  return (
    <div className="App">
      <Occupancy>
        <label
          htmlFor="radioTeacher"
          className={occupancyChecked === 0 ? "OccupancyChecked" : ""}
        >
          <input
            type="radio"
            name="occupancy"
            id="radioTeacher"
            onChange={changeOccupancyChecked}
            checked
          />
          <span>I'm a teacher</span>
        </label>
        <label
          htmlFor="radioStudant"
          className={occupancyChecked === 1 ? "OccupancyChecked" : ""}
        >
          <input type="radio" name="occupancy" id="radioStudant" />
          <span>I'm a studant</span>
        </label>
      </Occupancy>
    </div>
  );
}

How can this be fixed? display the className OccupancyChecked in the checked radio.


Solution

  • the default checked in radioTeacher is the main cause. I have updated it for better understanding.

    Working link

    import "./styles.css";
    import styled from "styled-components";
    import { useEffect, useState } from "react";
    
    const Occupancy = styled.label`
      display: flex;
      justify-content: space-between;
      margin-bottom: 1rem;
      font-size: 0.7rem;
      font-family: "Open Sans", sans-serif;
      font-weight: 400;
    
      label {
        border: 1px solid #6f49ed;
        background: #6f49ed;
        border-radius: 4px;
        padding: 1rem;
        text-transform: uppercase;
        width: 48%;
    
        input {
        }
    
        span {
          margin-left: 0.4rem;
        }
      }
      .OccupancyChecked {
        border: 1px solid rgba(255, 255, 255, 0.24);
        background: red;
      }
    `;
    
    export default function App() {
      const [occupancyChecked, setOccupancyChecked] = useState(0);
    
      const changeOccupancyChecked = (val) => {
        console.log("Value to set:", val);
        setOccupancyChecked(val);
        //occupancyChecked === 0 ? setOccupancyChecked(1) : setOccupancyChecked(0);
        //return;
      };
    
      return (
        <div className="App">
          <Occupancy>
            <label
              htmlFor="radioTeacher"
              className={occupancyChecked === 0 ? "OccupancyChecked" : ""}
            >
              <input
                type="radio"
                name="occupancy"
                id="radioTeacher"
                onChange={() => {
                  changeOccupancyChecked(0);
                }}
              />
              <span>I'm a teacher</span>
            </label>
            <label
              htmlFor="radioStudant"
              className={occupancyChecked === 1 ? "OccupancyChecked" : ""}
            >
              <input
                type="radio"
                name="occupancy"
                id="radioStudant"
                onChange={() => {
                  changeOccupancyChecked(1);
                }}
              />
              <span>I'm a studant</span>
            </label>
          </Occupancy>
        </div>
      );
    }