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.
CodePudding user response:
So i think your main issue is due to you using onChange instead of onClick.
Had a bit of a rework here if this is any use to show you what i changed https://stackblitz.com/edit/react-ts-queeta?file=Hello.tsx