Реагируйте: флажок не снимается, когда следующий вопрос приходит - PullRequest
1 голос
/ 02 февраля 2020

Я работаю над компонентом викторины, где пользователь может появиться для теста. Вопросы показываются пользователю один за другим, и пользователь проверяет правильный ответ.

Но я сталкиваюсь с проблемой ниже.

Описание: Флажок не снимает флажок для следующего вопроса. Он остается отмеченным, когда пользователь нажимает на любой из флажков.

Шаги: 1. Нажмите на любые варианты флажка для вопроса. enter image description here 2. Нажмите на следующий для следующего вопроса. [флажок отмечен в предыдущем вопросе] [enter image description here] 2

Ожидается: когда появляется следующий вопрос, флажок не должен быть установлен.

Факт: Когда следующий Появляются вопросы, флажок установлен.

Код: При щелчке следующего этот компонент получает данные в качестве реквизита от родительского компонента.

// This component show one question at a time
import React from 'react';
import TextEditorDisplay from '../../texteditor/TextEditorDisplay';
import Form from 'react-bootstrap/Form';

class TestComponent extends React.PureComponent {

    handleCheck = (e, idx) => {
        console.log('inside handleCheck',e.target.value)
        this.props.setAnswerGivenByUser(idx, e.target.checked);
    };

    render() {
        return (
            <div className="container">
                <h3 className="quiz-question">
                    <TextEditorDisplay editorContent={this.props.quizQuestion.question} />
                </h3>
                <Form>
                    <table>
                        <tbody>
                            {this.props.quizQuestion.options && this.props.quizQuestion.options.map((option, idx) => (
                                <tr key={idx}>
                                    <td>
                                        <Form.Group controlId="formBasicCheckbox">
                                            <Form.Check type="checkbox" value={option.data} onChange={e => this.handleCheck(e, idx)}/>
                                        </Form.Group>
                                    </td>
                                    <td>
                                        <p key={idx}>{option.data}</p>
                                    </td>
                                </tr>
                            ))}
                        </tbody>
                    </table>
                </Form>
            </div>
        );
    }
}

export default TestComponent;

Родительский компонент:

import React from 'react';
import TestComponent from '../components/skill-assessment/users/TestComponent';
import Button from 'react-bootstrap/Button';
import api from '../services/remote/api';

class TestHomePage extends React.PureComponent {
    x = 0;
    y = 0;
    arr = [];
    constructor(props) {
        super(props);
        this.getQuizQuestionsAsPerLevel = this.getQuizQuestionsAsPerLevel.bind(this);
        this.state = {
            quizQuestion: [],
            show: true,
            options: [],
            answers: []
        };
    }

    getIdFromUrl = () => {
        var url = this.props.location.pathname;
        var splitUrl = url.split('/');
        return splitUrl[2].toString();
    };

    componentDidMount() {
        this.getQuizQuestionsAsPerLevel(1);
        this.getQuizQuestionsAsPerLevel(2);
        this.getQuizQuestionsAsPerLevel(3);
        this.getQuizQuestionsAsPerLevel(4);
        this.getQuizQuestionsAsPerLevel(5);
        this.getQuizQuestionsAsPerLevel(6);
        console.log('component did mount arr', this.arr);
    }

    getQuizQuestionsAsPerLevel(level) {
        try {
            api.getQuizQuestionsAsPerLevel({ id: this.getIdFromUrl(), level: level }).then(response => {
                this.arr.push(response.data);
                console.log('arr inside api', this.arr);
            });
        } catch (exception) {
            console.log('exception', exception);
        }
    }

    addUserQandA() {
        try {
            api.addUserQandA({
                quizId: this.getIdFromUrl(),
                quizQandA: [{ quizQuestionId: this.state.quizQuestion._id }, { answers: this.state.answers }]
            }).then(response => {
                console.log('add QandA response', response);
            });
        } catch (exception) {
            console.log('exception', exception);
        }
    }

    nextQuestion = () => {
        // send prev Question data to QandA
        if (this.state.quizQuestion && this.state.answers) {
            this.addUserQandA();
        }
        if (this.x < this.arr.length - 1 && this.y >= this.arr[this.x].length) {
            this.x = this.x + 1;
            this.y = 0;
            this.setState({ quizQuestion: this.arr[this.x][this.y], answers: [] });
        } else if (this.x < this.arr.length && this.y < this.arr[this.x].length) {
            this.setState({ quizQuestion: this.arr[this.x][this.y] });
            this.y = this.y + 1;
        } else {
            // hide next button and highlight submit button
            this.setState({ show: false });
        }
    };

    setAnswerGivenByUser = (answerId, shouldAdd) => {
        const answers = this.state.answers.slice();
        if (shouldAdd) {
            if (!answers.includes(answerId)) {
                answers.push(answerId);
            }
        } else {
            if (answers.includes(answerId)) {
                const answerIndex = answers(a => a === answerId);
                answers.splice(answerIndex, 1);
            }
        }
        this.setState({ answers });
    };

    render() {
        console.log('answers', this.state.answers);
        return (
            <div className="container">
                <TestComponent quizQuestion={this.state.quizQuestion} setAnswerGivenByUser={this.setAnswerGivenByUser} />
                {this.state.show && (
                    <Button variant="primary" onClick={this.nextQuestion}>
                        Next
                    </Button>
                )}
                <Button variant="primary">Submit</Button>
            </div>
        );
    }
}

export default TestHomePage;

викторина Data Strcuture enter image description here

1 Ответ

2 голосов
/ 02 февраля 2020

Проблема необновления была вызвана не принудительным повторным отображением.

Для каждого уровня <tr /> элементы отображались с нумерацией key всегда начиная с 0 . Таким образом, рендеринг следующего уровня был выполнен при выходе из узлов (обновление), а не как новые. Первый неизмененный узел (в смысле того же реквизита) останавливает более глубокий анализ. В этом случае он останавливается на <Form.Group controlId="formBasicCheckbox"> - его дочерний элемент не обновляется, даже если option.data отличается.

Решение

key используется для отрисовки различных guish узлов в петлях. key должен быть уникальным. Это не должно быть только число ... они должны быть всегда уникальными.

Простое решение - использовать дополнительно пропущенный проп level:

<tr key={this.props.level * 10 + idx} />

На самом деле ... как <p key={idx}>{option.data}</p> был обновлен ... этого должно быть достаточно для использования этого (или аналогичного) уникального ключа / реквизита для <Form.Group/> (например, controlId). Используя уникальный на уровне <tr/>, мы форсируем рендеринг новой структуры (может быть дорогостоящим в некоторых сценариях ios).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...