简体   繁体   English

反应 onChange 只工作一次

[英]React onChange works only once

I'm trying to recreate the functionality of ToggleButtonGroup and ToggleButton from react-bootstrap.我正在尝试从 react-bootstrap 重新创建 ToggleButtonGroup 和 ToggleButton 的功能。

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 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:当我使用 react-bootstrap 时,唯一的区别是返回 function 看起来像这样:

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. onChange 事件仅在每个按钮上调用一次。

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.我已经在 Google 上找到了一些东西,但对我的情况没有用。

So i think your main issue is due to you using onChange instead of onClick.所以我认为您的主要问题是由于您使用 onChange 而不是 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如果这对向您展示我更改的内容有什么用,那么在这里进行了一些返工

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM