0

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.

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

4 Comments

It's working. But can you explain why? :) Also, the link doesn't work me.
Sorry not sure why the links not working maybe try in chrome?
The reason onChange wont work a second time is the value is already set so clicking it again shouldn't change anything but onClick wont care about the state so calling it again will register anyway. MDN HTMLElement: change event: developer.mozilla.org/en-US/docs/Web/API/HTMLElement/…
It doesn't load on Firefox. (not on my PC and not on my phone). Thanks for your answer though :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.