@PurgaBot

Какую логику сделать для проверки верности вопроса в приложении тест?

Я делаю приложение Тест и столкнулся с проблемой: я не понимаю как организовать логику проверки вопросов. Я создал функцию setAnswer с которой уже по разному экспериментировал, но все не получается сделать грамотную проверку правильного ответа и одновременно вывести верные ответы.
Вот код с функцией, проверяю на значение "yes".
App.js
import {useState} from 'react';
import './App.css';
import FientQuest from './FientQuest';
import {BrowserRouter,Route,Routes,Link} from 'react-router-dom';

export default function App(props) {

  const [answ,getAnsw] = useState(0);
  const [res,getRes] = useState(0);

const setAnswer = (event)=>{
  if (event.target.value === 'yes'){   
  //сама функция
}
}
const setReset = () =>{
  getAnsw(0);
  getRes(res + answ);
}
const setResult = ()=>{
  getAnsw(0);
  getRes(0);
}

  const questinsArray = props.store.map(store=> (
    <FientQuest 
    qmumb = {store.qmumb}
    quest = {store.quest}
    var1 = {store.var1}
    var2 = {store.var2}
    var3 = {store.var3}
    value1 = {store.value1}
    value2 = {store.value2}
    value3 = {store.value3}
    type = {store.type}
    id = {store.id}
    key = {store.id}
    name ={store.id}
    sTrund ={store.sTrund}
    setAnswer={setAnswer}
    />));

  return (
    <>
    <BrowserRouter>
      <div>
        <h1>Тест</h1> 
      <Routes>
      <Route path='/' element={<div className='cont'>
        {questinsArray}
        <Link to="/res"><button onClick={setReset}>Узнать результат</button></Link>
        </div>}/>
    <Route path='/res' element={<div>
          <h1>Ваш результат: {res}</h1>
          <Link to="/" onClick={setResult}><button >Вернуться назад</button></Link>
        </div>}/>
        </Routes> 
      </div>
      </BrowserRouter>
      </>
  );
}

Компонент с вопросами FientQuest
export default function FientQuest (props) {
      return (
      <div id={props.id}>
        <h4><span>{props.qmumb}</span> {props.quest}</h4>
        <label > {props.var1} 
        <input type={props.type} name={props.name} value={props.value1} onClick={(e)=>props.setAnswer(e)}/>
        </label>
        <label> {props.var2} 
        <input type={props.type} name={props.name}  value={props.value2} onClick={(e)=>props.setAnswer(e)}/>
        </label>
        <label > {props.var3} 
        <input type={props.type} name={props.name}  value={props.value3} onClick={(e)=>props.setAnswer(e)}/>
        </label>
       </div>
      );
  }

компонент с базой вопросов (если нужен будет) store.js
export const store =[
        {
                sTrund:"0",
        qmumb:"1",
        quest:" Скольки равна константа g=... используемая в формуле F=mg;",
        var1:"1) 9,8",
        var2:"2) 10,5",
        var3:"3) 6,62",
        value1: "yes",
        value2: "no",
        value3: "no",
        type:"radio",
        id:"quest-1"
        },
        {
                sTrund:"0",
        qmumb:"2",
        quest:" Кто из ученых 20 века пришел к понятию <<черного тела>> и поглощение телом частей энергии(квантов)",
        var1:"1) М. Планк",
        var2:"2) А. Лоренц",
        var3:"3) Б. Марли",
        value1: "yes",
        value2: "no",
        value3: "no",
        type:"radio",
        id:"quest-2"
        },
        {
                sTrund:"0",
        qmumb:"3",
        quest:" Кто заявил постулат в своей теории, что скорость света должна быть постоянна по отношению всех законов физики?",
        var1:"1) Ф. Мюрей",
        var2:"2) А. Эйнштейн",
        var3:"3) И. Ньютон",
        value1: "no",
        value2: "yes",
        value3: "no",
        type:"radio",
        id:"quest-3"
        }
]
  • Вопрос задан
  • 121 просмотр
Решения вопроса 1
0xD34F
@0xD34F Куратор тега React
Начать следует не с какой-то там логики, а со структуры данных, что содержит вопросы. То, что есть сейчас, никуда не годится. Что, если завтра вместо трёх вариантов ответа надо будет сделать четыре? Будете добавлять ещё по два свойства в каждый объект в массиве вопросов, а в компоненте закопипастите ещё один input? А если в разных вопросах должно будет быть разное количество вариантов ответа? Что тогда?

Варианты ответа складываете в массив, а корректный вариант обозначаете через его индекс:

const questions = [
  {
    text: 'Выберите верное утверждение',
    answers: [
      'СССР распался в 1997 году',
      'Солнце вращается вокруг Земли',
      'шестью восемь - двадцать три',
    ],
    correctAnswer: 1,
  },
  {
    text: '...',
    answers: [ '...', '...', ... ],
    correctAnswer: ...,
  },
  ...
];

В компоненте вопроса вместо того, чтобы копипастить input'ы, делаете цикл по вариантам ответа:

function Question(props) {
  const onChange = e => props.onAnswerChange(+e.target.value);

  return (
    <div>
      <h3>{props.question.text}</h3>
      <ol>
        {props.question.answers.map((n, i) => (
          <li>
            <label>
              <input
                type="radio"
                value={i}
                checked={props.answer === i}
                onChange={onChange}
              />
              {n}
            </label>
          </li>
        ))}
      </ol>
    </div>
  );
}

В родительском компоненте храните массив ответов:

function App(props) {
  const [ answers, setAnswers ] = useState(Array(props.questions.length).fill(null));

  const updateAnswer = (questionIndex, answer) =>
    setAnswers(answers.map((n, i) => i === questionIndex ? answer : n));

  return (
    <div>
      {props.questions.map((n, i) => (
        <Question
          question={n}
          answer={answers[i]}
          onAnswerChange={answer => updateAnswer(i, answer)}
        />
      ))}
    </div>
  );
}

Ну и возвращаясь к вашему вопросу, чего там надо было?

не получается сделать грамотную проверку правильного ответа...

Чтобы проверить правильность ответа, надо сравнить его со значением свойства correctAnswer у соответствующего (с тем же индексом) вопроса. Например, считаем количество правильных ответов:

const correctAnswersCount = answers.reduce((acc, n, i) => {
  return acc + (n === questions[i].correctAnswer);
}, 0);

...и одновременно вывести верные ответы

Поскольку свойство, обозначающее правильный ответ, является его индексом, просто достаём соответствующие элементы из массивов с вариантами ответа:

const correctAnswers = questions.map(n => n.answers[n.correctAnswer]);

Ну а массив строк вывести - надеюсь, справитесь сами.

UPD. Посмотреть живьём можно здесь (есть отличия от того, что есть или предполагается у вас - вопросы показываются по очереди, а не все сразу; в результатах отображаются только верные ответы).
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы