点击两次反应渲染

问题描述

因此,我和我的同事正在编写一个React / ServiceNow项目,供我们公司内部使用。 我正在使用reducer挂钩来管理整个应用程序的状态。我有以下结构的App组件,它们调用API(带有问题及其相应答案的数组)。此信息被传递到TrainingMode并返回

return 

    (
                <QuizContext.Provider value={{ state,dispatch }}>
                    <div className='container'>
                        <Progress />
                        {'Training'}
                        <Question />
                        {renderError()}
                        <Answers />
                        <button className='btn btn-primary' onClick={next}>
                            Confirm and Continue
                        </button>
                    </div>
                </QuizContext.Provider>
            );

答案:

function Answers() {
    const { state,dispatch } = useContext(QuizContext);
    const { currentAnswer,currentQuestion,questions } = state;
    const question = questions[currentQuestion].question;
    const answers = questions[currentQuestion].answers;
    console.log('curr ans is ' + question);
    console.log(answers);

    let firstLetter = 65;
    const ans = answers.map((el) => {
        return (
            <Answer
                key={el.sys_id}
                letter={(firstLetter++).toString()}
                answer={el.answer_text}
                answer_sysId={el.sys_id}
                selected={currentAnswer === el.sys_id}
                dispatch={dispatch}
            />
        );
    });

    return <>{ans}</>;

个人答案:

function Answer(props) {
    let classes = ['answer'];

    const handleClick = (e) => {
        props.dispatch({
            type: SET_CURRENT_ANSWER,currentAnswer: props.answer_sysId
        });
        props.dispatch({ type: SET_ERROR,error: '' });
    };

    if (props.selected) {
        classes.push('selected');
    }

    return (
        <button
            value={props.answer}
            className={classes.join(' ')}
            onClick={handleClick}
        >
            <span>{String.fromCharCode(props.letter)}.</span> {props.answer}
        </button>
    );
}

最后,是减速器:

function quizReducer(state,action) {
    switch (action.type) {
        case SET_CURRENT_ANSWER:
            console.log(action);
            state.currentAnswer.push(action.currentAnswer);
            return {
                ...state
                // currentAnswer: action.currentAnswer
            };
        case SET_CURRENT_QUESTION:
            return {
                ...state,currentQuestion: action.currentQuestion
            };
        case SET_ERROR:
            return {
                ...state,error: action.error
            };
        case SET_SHOW_RESULTS:
            return {
                ...state,showResults: action.showResults
            };
        case SET_ANSWERS:
            return {
                ...state,answers: action.answers
            };
        case ADD_CORRECT:
            return {
                ...state,correct: action.correct
            };
        case RESET_QUIZ:
            return {
                ...state,answers: [],currentQuestion: 0,currentAnswer: '',showResults: false,error: '',correct: 0
            };

        default:
            return state;
    }

我想单击每个答案并将其推送到currentAnswer数组(因此它适用于单选题和多选题)。这种工作方式可以将我单击的第一个答案推送一次,但是,当我单击其他答案时,会将它们推送两次。当我注释掉“严格”模式标记时,一切正常,但是我怀疑这是最好的解决方案。 console log

我已经阅读了一些文章,但似乎无法解决此问题。

解决方法

Ciao,您知道呈现组件时,会触发触发器useEffect钩子。因此,您可以尝试将日志记录在此钩子中。像这样:

import { useEffect } from 'react';
...
useEffect(() => {
   console.log('curr ans is ' + question);
   console.log(answers);
})

如果日志出现两次,则Answer组件将呈现两次。否则不行。 现在是一个问题:为什么您看到日志翻倍?我的答案是我不知道。可能与react工作流程有关,但这只是我的看法(我不是React的专家)。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...