skip to Main Content

I have tried multiple ways and checked for solutions already but none of them seem to work.

I cannot fire onChange for radio buttons. Following is my code:

const [rate, setRate] = useState<any>("");

const handleRate = (e: any) => {
    console.log("HI")
    setRate(e.target.value);
  };

<div className="col">
              <div className="rate">
                <input type="radio" id="star5" className="rate" name="rate"
                  value="5" onChange={handleRate} checked={rate === '5'} />
                <label htmlFor="5" title="text">5 stars</label>
                <input type="radio" id="star4" className="rate" name="rate"
                  value="4" onChange={handleRate} checked={rate === '4'} />
                <label htmlFor="4" title="text">4 stars</label>
                <input type="radio" id="star3" className="rate" name="rate"
                  value="3" onChange={handleRate} checked={rate === '3'} />
                <label htmlFor="3" title="text">3 stars</label>
                <input type="radio" id="star2" className="rate" name="rate"
                  value="2" onChange={handleRate} checked={rate === '2'} />
                <label htmlFor="2" title="text">2 stars</label>
                <input type="radio" id="star1" className="rate" name="rate"
                  value="1" required onChange={handleRate} defaultChecked={rate === '1'} />
                <label htmlFor="1" title="text">1 star</label>
              </div>
       </div>

Update: CSS is causing this issue.

.rate { float: left; height: 46px; padding: 0 10px; }

.rate:not(:checked)>input { position: absolute; display: none; }

.rate:not(:checked)>label { float: right; width: 1em; overflow:
hidden; white-space: nowrap; cursor: pointer; font-size: 30px;
color: #ccc; }

.rated:not(:checked)>label { float: right; width: 1em; overflow:
hidden; white-space: nowrap; cursor: pointer; font-size: 30px;
color: #ccc; }

.rate:not(:checked)>label:before { content: ‘★ ‘; }

.rate>input:checked~label { color: #ffc700; }

.rate:not(:checked)>label:hover, .rate:not(:checked)>label:hover~label
{ color: #deb217; }

.rate>input:checked+label:hover,
.rate>input:checked+label:hover~label,
.rate>input:checked~label:hover,
.rate>input:checked~label:hover~label,
.rate>label:hover~input:checked~label { color: #c59b08; }

.star-rating-complete { color: #c59b08; }

.rating-container .form-control:hover, .rating-container
.form-control:focus { background: #fff; border: 1px solid #ced4da;
}

.rating-container textarea:focus, .rating-container input:focus {
color: #000; }

.rated { float: left; height: 46px; padding: 0 10px; }

.rated:not(:checked)>input { position: absolute; display: none; }

.rated:not(:checked)>label { float: right; width: 1em; overflow:
hidden; white-space: nowrap; cursor: pointer; font-size: 30px;
color: #ffc700; }

.rated:not(:checked)>label:before { content: ‘★ ‘; }

.rated>input:checked~label { color: #ffc700; }

.rated:not(:checked)>label:hover,
.rated:not(:checked)>label:hover~label { color: #deb217; }

.rated>input:checked+label:hover,
.rated>input:checked+label:hover~label,
.rated>input:checked~label:hover,
.rated>input:checked~label:hover~label,
.rated>label:hover~input:checked~label { color: #c59b08; }

2

Answers


  1. Chosen as BEST ANSWER

    I found the solution. The code was working fine and doing its job. The reason why it wasn't firing onChange is because of CSS.

    In the CSS part, it requires radio button's label. The label "htmlFor" or "for" should be same as input radio's id. This fixed the solution.


  2. I think it works properly.

    I made a demo in this React Playground: https://playcode.io/1275917

    import React, { useState } from 'react';
    
    export function App(props) {
    
      const [rate, setRate] = useState("");
      const handleRate = (e) => {
        console.log(e.target.value);
        setRate(e.target.value);
      };
    
      return (
        <div className='App'>
          <h1>Hello React.</h1>
          <h2>Start editing to see some magic happen!</h2>
    
          <div className="col">
                  <div className="rate">
                    <input type="radio" id="star5" className="rate" name="rate"
                      value="5" onChange={handleRate} checked={rate === '5'} />
                    <label htmlFor="5" title="text">5 stars</label>
                    <input type="radio" id="star4" className="rate" name="rate"
                      value="4" onChange={handleRate} checked={rate === '4'} />
                    <label htmlFor="4" title="text">4 stars</label>
                    <input type="radio" id="star3" className="rate" name="rate"
                      value="3" onChange={handleRate} checked={rate === '3'} />
                    <label htmlFor="3" title="text">3 stars</label>
                    <input type="radio" id="star2" className="rate" name="rate"
                      value="2" onChange={handleRate} checked={rate === '2'} />
                    <label htmlFor="2" title="text">2 stars</label>
                    <input type="radio" id="star1" className="rate" name="rate"
                      value="1" required onChange={handleRate} defaultChecked={rate === '1'} />
                    <label htmlFor="1" title="text">1 star</label>
                  </div>
           </div>
        </div>
      );
    }
    
    // Log to console
    console.log('Hello console')
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search