skip to Main Content

I’m working on a React form where I’m trying to change the background color of a label when a radio button is selected, but when I click/check the button it first update the state and on second click it shows me the background color.

I’m using a combination of onChange and checked attributes to manage the radio button state.

I have go through the Chat-GPT but it is still not answering me correctly

Below is the code for the Task component and CSS.

import React, { useState } from 'react';

export default function Task() {
  let [formData, setformData] = useState({
    uName: '', 
    uGender: '', 
    uMedals: 0, 
  });

  let handleForm = (e) => {
    let { name, value } = e.target;
    if (name === 'uMedals') {
      value = parseInt(value);
      if (value <= 0){ 
          value = 0;
      if (value > 20) 
          value = formData.uMedals;
    }
    setformData((formData) => ({
      ...formData,
      [name]: value,
    }));
    e.preventDefault();
  };

  return (
    <div className='parent-container'>
      <div className='content-wrapper'>
        <div className='left'>
          <form className='form-wrapper'>
            <div className='name-wrapper'>
              <label>Name</label>
              {/* Name input */}
            </div>
            <div className='toogle-wrapper'>
              <label className='lbl-gen'>Gender</label>
              <div className='wrapper'>
                <div className='custom-input'>
                  <input
                    type='radio'
                    id='female'
                    name='uGender'
                    value='female'
                    onChange={handleForm}
                    checked={formData.uGender === 'female'}
                  />
                  <label htmlFor='female'>Female</label>
                </div>
                <div className='custom-input'>
                  <input
                    type='radio'
                    id='male'
                    name='uGender'
                    value='male'
                    onChange={handleForm}
                    checked={formData.uGender === 'male'}
                  />
                  <label htmlFor='male'>Male</label>
                </div>
              </div>
            </div>
            <button style={{ width: '320px' }}>Add</button>
          </form>
        </div>
      </div>
    </div>
  );
}

The below is the CSS code of above Task component

.custom-input input[type=radio] {
    display: none;
}
.custom-input label {
    display: block;
    padding: 6px 8px;
    color: #fff;
    font-weight: bold;
    text-align: center;
    transition: all 0.4s ease;
    cursor: pointer;
    border-radius: 4px;
    background-color: #717762;
}
.custom-input input[type='radio']:checked + label {
    background-color: #f5f5f5; 
    color: #000;
}

2

Answers


  1. In your CSS, you’re using the sibling combinator (+), which only applies styles to the that is immediately following the . This means that your CSS rule will only affect labels that are direct siblings of the radio inputs.

    Keep the label immediately after the input within the same .custom-input container.

    Login or Signup to reply.
  2. You need to remove e.preventDefault() from handleForm function to change background color on first click.

    function Task() {
      const [formData, setformData] = React.useState({
        uName: "",
        uGender: "",
        uMedals: 0,
      });
    
      const handleForm = (e) => {
        let { name, value } = e.target;
        if (name === "uMedals") {
          value = parseInt(value);
          if (value <= 0) value = 0;
          if (value > 20) value = formData.uMedals;
        }
        setformData((formData) => ({
          ...formData,
          [name]: value,
        }));
      };
    
      return (
        <div className="parent-container">
          <div className="content-wrapper">
            <div className="left">
              <form className="form-wrapper">
                <div className="name-wrapper">
                  <label>Name</label>
                  {/* Name input */}
                </div>
                <div className="toogle-wrapper">
                  <label className="lbl-gen">Gender</label>
                  <div className="wrapper">
                    <div className="custom-input">
                      <input
                        type="radio"
                        id="female"
                        name="uGender"
                        value="female"
                        onChange={handleForm}
                        checked={formData.uGender === "female"}
                      />
                      <label htmlFor="female">Female</label>
                    </div>
                    <div className="custom-input">
                      <input
                        type="radio"
                        id="male"
                        name="uGender"
                        value="male"
                        onChange={handleForm}
                        checked={formData.uGender === "male"}
                      />
                      <label htmlFor="male">Male</label>
                    </div>
                  </div>
                </div>
                <button style={{ width: "320px" }}>Add</button>
              </form>
            </div>
          </div>
        </div>
      );
    }
    
    ReactDOM.render(<Task />, document.getElementById("root"));
    .custom-input input[type=radio] {
        display: none;
    }
    .custom-input label {
        display: block;
        padding: 6px 8px;
        color: #fff;
        font-weight: bold;
        text-align: center;
        transition: all 0.4s ease;
        cursor: pointer;
        border-radius: 4px;
        background-color: #717762;
    }
    .custom-input input[type='radio']:checked + label {
        background-color: #f5f5f5; 
        color: #000;
    }
    <div id="root"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search