I'm trying to recreate the functionality of ToggleButtonGroup and ToggleButton from react-bootstrap.
Here's my component:
import { useState } from 'react'; import ButtonRadio from "PointAndClick/components/ButtonRadio"; import { useSelector } from 'react-redux'; import { RootState } from '../../features/store'; import '../css/GameAnswers.css'; import GameImage from '../components/GameImage'; type GameAnswersProps = { setFinishedGame: Function } function GameAnswers(props: GameAnswersProps) { const gameAnswers = useSelector((state: RootState) => state.GameDataReducer.gameAnswers); const gameImages = useSelector((state: RootState) => state.GameDataReducer.gameImages); const correctAnswer = useSelector((state: RootState) => state.GameDataReducer.correctAnswers); const gameQuestion = useSelector((state: RootState) => state.GameDataReducer.gameQuestion); const [selectedAnswer, setSelectedAnswer] = useState(""); let iconAnswer = ""; const handleAnswerChange = function (e: React.ChangeEvent<HTMLInputElement>) { console.log(e.target); setSelectedAnswer(e.target.value); } const determineButtonVariant = function (answer: string) { if (answer !== selectedAnswer) { return "primary"; } else if (answer === correctAnswer) { props.setFinishedGame(true); iconAnswer="check"; return "success"; } else { props.setFinishedGame(false); iconAnswer="times"; return "danger"; } } return ( <div className="game-answers"> { gameImages === undefined && <GameImage className="game-details-image" images={[{ imgSrc: gameQuestion, imgAlt: 'test' }]} /> } <div className="btn-group btn-group-custom"> {gameAnswers.map(function (answer, index) { return <ButtonRadio id={answer} value={answer} onChange={handleAnswerChange} className={`btn btn-${determineButtonVariant(answer)}${gameImages !== undefined ? "btn-img" : ""}`} > {gameImages !== undefined && <GameImage className="game-answers-image" images={[{ imgSrc: gameImages[index], imgAlt: 'test' }]} /> } {iconAnswer !== "" && determineButtonVariant(answer) !== "primary" ? <i className={`fa fa-${iconAnswer} fa-${iconAnswer}-custom`}/> : "" } {answer} </ButtonRadio> })} </div> </div> ); } export default GameAnswers; ButtonRadio.tsx
import "../css/Button.css"; type ButtonRadioProps = { className: string, children: React.ReactNode, name: string, id?: string, value?: string, onChange?: any } function ButtonRadio(props: ButtonRadioProps) { return ( <> <input type="radio" id={props.id} value={props.value} className="btn-check" onChange={props.onChange} autoComplete="off" /> <label className={props.className} htmlFor={props.id} role="button" tabIndex={0} > {props.children} </label> </> ); } export default ButtonRadio; When I was using react-bootstrap, the only difference was the return function which looked like this:
return ( <div className="game-answers"> { gameImages === undefined && <GameImage className="game-details-image" images={[{ imgSrc: gameQuestion, imgAlt: 'test' }]} /> } <ToggleButtonGroup type="radio" name="answers" className="btn-group-custom"> {gameAnswers.map(function (answer, index) { return <ToggleButton id={answer} value={answer} onChange={handleAnswerChange} variant={determineButtonVariant(answer)} bsPrefix={gameImages !== undefined ? "btn-img" : ""} > {gameImages !== undefined && <GameImage className="game-answers-image" images={[{ imgSrc: gameImages[index], imgAlt: 'test' }]} /> } {iconAnswer !== "" && determineButtonVariant(answer) !== "primary" ? <i className={`fa fa-${iconAnswer} fa-${iconAnswer}-custom`}/> : "" } {answer} </ToggleButton> })} </ToggleButtonGroup> </div> ); and everything worked fine.
Now I tried to do it myself (the first piece of code in the post) and it works but only partially.
The onChange event is only called once on each button.
Example:
I click on answer1: onChange called I click on answer2: onChange called I click on answer1 again: onChange isn't called anymore (I expected it to be called again) Why can this be happening and how can I fix it? I found already something on Google, but not useful to my case.