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
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.
I think it works properly.
I made a demo in this React Playground: https://playcode.io/1275917