So here is my component:
import React, { MouseEvent, useState } from 'react';
import { Button } from 'react-bootstrap';
import './css/GameAnswers.css';
type Answers = {
arrayAnswers: Array<string>,
correctAnswer: string
}
function GameAnswers(props: Answers)
{
const [buttonClass, setClass] = useState('');
function submitAnswer(e: MouseEvent)
{
if((e.target as HTMLInputElement).getAttribute('data-key') === props.correctAnswer)
{
e.preventDefault();
setClass("btn-success");
return;
}
setClass("btn-danger");
}
return (
<div className="game-answers">
{props.arrayAnswers.map(function(answer){
return <Button className={`game-answer ${buttonClass}`} data-key={answer} onClick={submitAnswer}>{answer}</Button>;
})}
</div>
);
}
export default GameAnswers;
and here's how I render it:
<GameAnswers arrayAnswers={['Yes', 'No']} correctAnswer="Yes"/>
when the user presses on Yes, I want to add the class "btn-success" to the button with Yes. When the user presses on No, I want to add the class "btn-danger" to the button with No.
How can I do that while still using map? (I might have multiple buttons in the future)
CodePudding user response:
I would approach this a little differently:
- Use a
ToggleButtonGroup
as this will get you the multiple choice behavior out of the box. - Use the
variant
property set the look and feel, rather than manually toggling CSS classes
Below an alternate version of your code with the above suggestions. Check out the link below for a live demo of this version.
Click here for a Code Sandbox Demo
import React, { useState } from "react";
import { ToggleButtonGroup, ToggleButton } from "react-bootstrap";
type Answers = {
arrayAnswers: Array<string>;
correctAnswer: string;
};
const GameAnswers: React.FC<Answers> = ({ arrayAnswers, correctAnswer }) => {
const [selectedAnswer, setSelectedAnswer] = useState("");
const handleAnswerChange = (e: React.ChangeEvent<HTMLInputElement>) =>
setSelectedAnswer(e.currentTarget.value);
const determineButtonVariant = (answer: string) => {
if (answer !== selectedAnswer) {
return "primary";
} else if (answer === correctAnswer) {
return "success";
} else {
return "danger";
}
};
return (
<div className="game-answers">
<ToggleButtonGroup name="answers">
{arrayAnswers.map(function (answer) {
return (
<ToggleButton
id={answer}
value={answer}
onChange={handleAnswerChange}
variant={determineButtonVariant(answer)}
>
{answer}
</ToggleButton>
);
})}
</ToggleButtonGroup>
</div>
);
};
export default GameAnswers;
CodePudding user response:
This works for me can you try? (If there are typescript errors, you need to fix it.)
import ButtonWrapper from "./ButtonWrapper ";
type Answers = {
arrayAnswers: Array<string>;
correctAnswer: string;
};
function GameAnswers(props: Answers) {
return (
<div className="game-answers">
{props.arrayAnswers.map(function (answer, index) {
return (
<ButtonWrapper
key={index}
answer={answer}
correctAnswer={props.correctAnswer}
/>
);
})}
</div>
);
}
ButtonWrapper/index.js
type Props= {
answer: string;
correctAnswer: string;
};
function ButtonWrapper(props: Props) {
const [customClass, setCustomClass] = useState("");
return (
<Button
className={`game-answer ${customClass}`}
onClick={() => {
if (props.answer === props.correctAnswer) {
setCustomClass("btn-success");
} else {
setCustomClass("btn-danger");
}
}}
>
{props.answer}
</Button >
);
}