Реагирование — подсчет установленных флажков

#javascript #reactjs

#javascript #reactjs

Вопрос:

У меня возникли некоторые проблемы с некоторыми флажками в моем компоненте React здесь: https://codesandbox.io/s/quiz-4uyde ?file=/src/App.js

Проблема, с которой я сталкиваюсь, заключается в том, что при проверке двух правильных ответов оценка отражается неправильно. Я пытаюсь настроить его так, чтобы при проверке правильного ответа оценка увеличивалась на единицу. это увеличение должно быть удалено, когда правильный ответ не отмечен. Любой балл не должен увеличиваться или уменьшаться, если отмечен неправильный ответ. однако по первому вопросу здесь, когда я проверяю один правильный ответ, оценка увеличивается, но когда я проверяю второй правильный ответ, оценка уменьшается.

Если у кого-то есть предложения, мы будем признательны!

Ответ №1:

Вы должны использовать useState для отслеживания checked ответов на протяжении всего теста. Чтобы сделать это, я переместил целые вопросы в useState и добавил новое свойство к каждому checked: false .

 const [questions, setQuestions] = useState(initialQuestions);
 

Для управления щелчком пользователя у вас есть функция handleAnswerOptionClick . Основной вывод из этой функции заключается в том, что только при нажатии на ответ должно быть checked переключено его состояние ( checked: !previousCheckedValue ) . В отношении вопросов с типом select , когда пользователь нажимает на один вопрос, все остальные будут сняты автоматически.

 const handleAnswerOptionClick = (e, questionId) => {
const answerTextValue = e.target.value;
const updatedQuestions = questions.map((question) => {
  if (question.id === questionId) {
    const updatedAnswersOptions = question.answerOptions.map((answer) => {
      if (answer.answerText === answerTextValue) {
        return { ...answer, checked: !answer.checked };
        } else {
          return question.questionType === "select"
            ? { ...answer, checked: false }
            : answer;
        }
      });
      return { ...question, answerOptions: updatedAnswersOptions };
      } else {
       return question;
      }
    });
    setQuestions(updatedQuestions);
  };
 

В дополнение к управлению checked состоянием, вы также можете включить useMemo перехват для вычисления количества правильных ответов внутри всех вопросов. Пожалуйста, обратите внимание, что если в ответе было выбрано несколько правильных ответов на определенный вопрос, оценка будет увеличена на количество правильных ответов.

     const score = useMemo(() => {
    return questions.reduce((acc, q) => {
      const correctAnswerSelected = q.answerOptions.reduce((acc, answer) => {
        if (answer.checked amp;amp; answer.isCorrect) {
          acc = acc   1;
        }
        return acc;
      }, 0);
      acc = acc   correctAnswerSelected;

      return acc;
    }, 0);
  }, [questions]);
 

Вот рабочий codesandbox: https://codesandbox.io/s/quiz-forked-vbt6o?file=/src/App.js

Комментарии:

1. Спасибо за вашу помощь. Единственное, что на вопрос 1, если выбраны оба правильных ответа, он показывает только «1» для оценки

2. И вы хотите, чтобы это считалось как 2?

3. да, я бы хотел, чтобы это считалось как 2

4. Я отредактировал ответ, изменение находится внутри useMemo . Удачи 🙂

5. я вижу обновленную песочницу, и теперь она действительно работает. БОЛЬШОЕ ВАМ СПАСИБО!

Ответ №2:

Я думаю, что вы, возможно, неправильно обрабатываете состояние. То, что вы делаете, — это устанавливаете статические элементы и проверяете по щелчку, если они верны, но не если это не так. таким образом, вот что происходит не так:

  1. Вы не отслеживаете, что проверено, а что нет
  2. Вы не отслеживаете неправильный ответ, только если на него нажали.

Что вы могли бы сделать вместо этого, так это установить флажок внутри ваших вариантов ответов:

 answerOptions: [
        { answerText: "New York", isCorrect: false, checked: false },
        { answerText: "London", isCorrect: false, checked: false },
        { answerText: "Paris", isCorrect: true, checked: false },
        { answerText: "Dublin", isCorrect: true, checked: false }
      ]
 

Затем в вашем handleChange передайте элемент и измените проверенное значение на true.

После этого все, что вам нужно сделать, это обновить счет:

 setScore(score.filter(a => a.isCorrect amp;amp; a.checked).length)
 

Note that this won't remove point for wrong answers, but you can also have it this way

 setScore(answers.filter(a => a.isCorrect amp;amp; a.checked).length - answers.filter(a => !a.isCorrect amp;amp; a.checked).length)
 

и установите ответы на ответы текущего вопроса

Редактировать

Забыл упомянуть об ответах в последней части.

Комментарии:

1. Спасибо, Алекс, это действительно полезно. Не могли бы вы объяснить немного больше о том, как вы будете обновлять handleChange?

2. Прежде всего, для вашего проверяемого значения должно быть установлено значение checked свойства вашего answerOption. Во-вторых, в вашем handleChange вы должны обновить состояние, чтобы отразить, что ответ теперь проверен В-третьих, вы обновляете оценку Большая проблема прямо сейчас, и именно поэтому я на самом деле не использую хуки, заключается в том, что ваши вопросы не могут быть обновлены, потому что они являются реквизитами и, следовательно, неизменяемыми. Вам также следует подумать о том, чтобы иметь их в состоянии, чтобы их можно было обновлять