Хук React useState
позволяет нам отслеживать состояние функционального компонента.
Состояние обычно относится к данным или свойствам, которые необходимо отслеживать в приложении.
Здесь, в этой статье, я сделал простое приложение для викторины, используя хук useState, у меня нет базы данных для хранения вопросов и ответов, поэтому сейчас я использую массив для хранения. цель написания этой статьи состоит в том, чтобы просто немного глубже описать хук useState.
я объясню каждую строку кода, пожалуйста, проверьте вывод кода в ваших браузерах, прежде чем переходить к пояснительной части.
import { useState } from 'react'; function QuizApp() { const [currentQuestion, setCurrentQuestion] = useState(0); const [score, setScore] = useState(0); const [quizFinished, setQuizFinished] = useState(false); const questions = [ 'What is the capital of France?', 'What is the largest planet in our solar system?', 'What is the smallest country in the world by land area?' ]; const answers = [ ['Paris', 'Berlin', 'Rome', 'Madrid'], ['Jupiter', 'Saturn', 'Mars', 'Neptune'], ['Vatican City', 'Monaco', 'Nauru', 'San Marino'] ]; const handleAnswer = (answer) => { if (answer === answers[currentQuestion][0]) { setScore(score + 1); } if (currentQuestion < questions.length - 1) { setCurrentQuestion(currentQuestion + 1); } else { setQuizFinished(true); } }; return ( <div> <h1>Quiz App</h1> {quizFinished ? ( <> <p>Quiz finished! Final score: {score}/{questions.length}</p> </> ) : ( <> <p>Question {currentQuestion + 1}: {questions[currentQuestion]}</p> {answers[currentQuestion].map((answer) => ( <button key={answer} onClick={() => handleAnswer(answer)}>{answer}</button> ))} <p>Score: {score}/{questions.length}</p> </> )} </div> ); } export default QuizApp;
Я был бы рад объяснить каждую строку кода:
import { useState } from 'react';
Это импортирует хук useState
из библиотеки React. Мы используем его для объявления переменных состояния, которые мы можем изменять в ответ на действия пользователя или другие изменения.
function QuizApp() { const [currentQuestion, setCurrentQuestion] = useState(0); const [score, setScore] = useState(0); const [quizFinished, setQuizFinished] = useState(false);
Это определяет новый компонент с именем QuizApp
и объявляет три переменные состояния с помощью хука useState
. currentQuestion
отслеживает индекс текущего отображаемого вопроса, score
отслеживает количество правильных ответов, данных на данный момент, а quizFinished
отслеживает, завершен ли тест.
const questions = [ 'What is the capital of France?', 'What is the largest planet in our solar system?', 'What is the smallest country in the world by land area?']; const answers = [ ['Paris', 'Berlin', 'Rome', 'Madrid'], ['Jupiter', 'Saturn', 'Mars', 'Neptune'], ['Vatican City', 'Monaco', 'Nauru', 'San Marino'] ];
Это массивы, которые определяют вопросы и соответствующие варианты ответов для викторины. Каждый вопрос представлен в виде строки, а каждый набор вариантов ответа представляет собой массив строк.
const handleAnswer = (answer) => { if (answer === answers[currentQuestion][0]) { setScore(score + 1); } if (currentQuestion < questions.length - 1) { setCurrentQuestion(currentQuestion + 1); } else { setQuizFinished(true); } };
Это функция, которая вызывается, когда пользователь выбирает ответ на вопрос. Он проверяет правильность ответа, сравнивая его с первым вариантом ответа в массиве answers
для текущего вопроса. Если это правильно, он увеличивает переменную состояния score
на 1, используя функцию setScore
. Затем он проверяет, есть ли еще вопросы для отображения, сравнивая currentQuestion
с длиной массива questions
. Если вопросов больше, он увеличивает currentQuestion
на 1 с помощью функции setCurrentQuestion
. Если вопросов больше нет, он устанавливает quizFinished
в true
с помощью функции setQuizFinished
.
return ( <div> <h1>Quiz App</h1> {quizFinished ? ( <> <p>Quiz finished! Final score: {score}/{questions.length}</p> </> ) : ( <> <p>Question {currentQuestion + 1}: {questions[currentQuestion]}</p> {answers[currentQuestion].map((answer) => ( <button key={answer} onClick={() => handleAnswer(answer)}>{answer}</button> ))} <p>Score: {score}/{questions.length}</p> </> )} </div> );
- Мы возвращаем
div
, который содержит содержимое нашего приложения-викторины. - Мы отображаем элемент
h1
с заголовком нашего приложения. - Мы проверяем, завершена ли викторина, используя переменную
quizFinished
. Если этоtrue
, мы показываем окончательный счет. Если этоfalse
, мы показываем текущий вопрос и ответы. - Если викторина завершена, мы отображаем элемент
p
с окончательным счетом. Мы используем литералы шаблонов для отображения текущего счета и общего количества вопросов. - Если викторина не завершена, мы отображаем текущий номер вопроса и сам вопрос. Мы используем литералы шаблонов для отображения текущего номера вопроса и текста вопроса.
{answers[currentQuestion].map((answer) => ( <button key={answer} onClick={() => handleAnswer(answer)}>{answer}</button> ))}
- Это сопоставляет варианты ответов для текущего вопроса и создает элемент
button
для каждого варианта ответа. Свойствоkey
установлено на строкуanswer
для уникальной идентификации каждого элемента кнопки. СвойствоonClick
настроено на функцию обратного вызова, которая вызывает функциюhandleAnswer()
с выбранным ответом. - Мы также отображаем список ответов на текущий вопрос с помощью функции
map
. Для каждого ответа в массивеanswers
мы создаем элементbutton
с текстом ответа в качестве метки кнопки. Мы используем атрибутkey
для присвоения уникального идентификатора каждому элементу кнопки. Мы также добавляем обработчик событияonClick
к каждому элементу кнопки, который вызывает функциюhandleAnswer
, когда пользователь нажимает кнопку. - Наконец, мы отображаем текущий счет, используя элемент
p
. Мы используем литералы шаблонов для отображения текущего счета и общего количества вопросов.