[ad_1]

Neste tutorial do React para iniciantes, vamos construir um aplicativo de teste. Trabalharemos com objetos de estado complexos, como lidar com ganchos de estado diferentes e renderizar coisas com base no estado.

Confira:

project

Tente você mesmo

Se você quiser experimentar primeiro, aqui estão os cenários (você também pode pegar o código inicial abaixo):

  • Quando o usuário clica em um botão, a próxima pergunta deve mostrar
  • Se o usuário acertar a pergunta, deve aumentar sua pontuação
  • Quando o usuário chega ao final do questionário, sua pontuação total deve ser mostrada

Passo a passo de vídeo

Código Inicial

Pegue-o no GitHub aqui.

Vamos lá!

Se você abrir o código inicial e vá para App.js, você verá que forneci uma lista de perguntas / respostas, armazenada como uma matriz chamada questões. Este é o nosso teste.

Nosso primeiro objetivo é pegar os dados da pergunta do array e exibi-los na tela.

Vamos remover o texto codificado e pegar os dados da primeira pergunta por enquanto, apenas para fazer as coisas andarem. Vamos nos preocupar em mudar de pergunta mais tarde.

Em nosso JSX, remova o texto da pergunta codificado e digite {questions[0]} para obter o primeiro item (ou pergunta) em nossa matriz de perguntas.

<div className="question-text">{questions[0]}</div>

Renderizando as perguntas e respostas

A primeira questão é um objeto, portanto podemos usar “notação de ponto” para obter acesso às propriedades. Agora vamos apenas fazer {question[0].questionText} para obter acesso ao texto da pergunta para este objeto:

<div className="question-text">{questions[0].questionText}</div>

Salve e execute o aplicativo. Observe como o texto é atualizado. Lembre-se de que estamos apenas pegando o primeiro texto de pergunta do primeiro objeto em nosso array de perguntas.

Faremos uma abordagem semelhante para as opções de resposta. Remova os botões codificados e usaremos a função de mapa para repetir as opções de resposta para uma determinada pergunta.

Lembre-se de que a função map faz um loop sobre o array e nos dá o item atual em que o loop está, na forma de uma variável.

Substitua o div “answer-section” pelo seguinte:

<div className="answer-section">	{questions[0].answerOptions.map((answerOption, index) => (		<button>{answerOption.answerText}</button>	))}</div>

Salve e execute o aplicativo. Observe como quatro botões de resposta aparecem e o texto é renderizado dinamicamente.

Vamos recapitular:

  • Estamos recebendo a primeira pergunta do conjunto de perguntas: questions[0]
  • A primeira pergunta é um objeto, que contém uma matriz de answerOptions. Podemos chegar a esta matriz usando a notação de ponto: questions[0].answerOptions
  • Porque o answerOptions é uma matriz, podemos mapear sobre isto: questions[0].answerOptions.map
  • Dentro da função do mapa, renderizamos um botão para cada answerOption, e exibir o texto

Alterando perguntas usando estado

Agora vamos voltar ao nosso JSX. Observe como se mudarmos questions[0] para questions[1], ou questions[2], a IU será atualizada. Isso ocorre porque ele está pegando os dados de diferentes questões em nossa matriz de questões, dependendo do índice.

O que queremos fazer é usar um objeto de estado para manter em qual pergunta o usuário está atualmente e atualizar isso quando um botão de resposta for clicado. Você pode ver isso executando o código no exemplo final.

Vá em frente e adicione um objeto de estado, que conterá o número da pergunta atual o usuário está ligado. Isso será inicializado com 0 para que o questionário responda a primeira pergunta da matriz:

const [currentQuestion, setCurrentQuestion] = useState(0);

Agora queremos substituir o ‘0’ codificado em nosso JSX por esta variável. Primeiro para o texto da pergunta:

<div className="question-text">{questions[currentQuestion].questionText}</div>

E também para a seção de perguntas:

<div className="answer-section">	{questions[currentQuestion].answerOptions.map((answerOption, index) => (		<button>{answerOption.answerText}</button>	))}</div>

Agora, se você inicializar o currentQuestion para algo diferente de 0, por exemplo 1 ou 2, a IU será atualizada para mostrar a pergunta e as respostas para essa pergunta específica. Muito legal!

Vamos adicionar algum código para que, quando clicarmos em uma resposta, incrementemos o currentQuestion valor para nos levar à próxima pergunta.

Crie uma nova função chamada handleAnswerButtonClick. Isso é o que será chamado quando o usuário clicar em uma resposta.

Vamos incrementar o valor da pergunta atual em um, salvá-lo em uma nova variável e definir esta nova variável no estado:

const handleAnswerButtonClick = (answerOption) => {	const nextQuestion = currentQuestion + 1;	setCurrentQuestion(nextQuestion);};

Em seguida, adicione um evento onClick ao nosso botão, assim:

<button onClick={() => handleAnswerButtonClick()}>{answerOption.answerText}</button>

Se tentarmos fazer isso, você verá que funciona, até chegarmos ao fim:

error

Então oque está acontecendo? Bem em nosso handleAnswerButtonClick função, estamos incrementando o número e configurando-o para o estado. Isso está ok.

Mas lembre-se de que usamos esse número para acessar um array, a fim de obter as opções de pergunta e resposta. Assim que chegarmos ao 5, ele irá quebrar, pois não existe o 5º elemento!

Vamos verificar se não ultrapassamos o limite. Em nossa função handleAnswerButtonClick, vamos adicionar a seguinte condição:

if (nextQuestion < questions.length) {	setCurrentQuestion(nextQuestion);} else {	alert('you reached the end of the quiz');}

Isso basicamente diz que se o número da próxima pergunta for menor que o número total de perguntas, atualize o estado para a próxima pergunta. Caso contrário, chegamos ao final do questionário, então mostre um alerta por enquanto.

Mostrando a tela de pontuação

Em vez de mostrar um alerta, o que queremos fazer é mostrar a tela de “pontuação”.

Se olharmos para o JSX, você notará que coloquei a marcação aqui para você, só precisamos substituir “false” pela lógica.

Então, como vamos fazer isso? Bem, isso é uma coisa perfeita para colocar no estado!

Adicione outro objeto de estado que armazenará se queremos mostrar a tela de pontuação ou não:

const [showScore, setShowScore] = useState(false);

E substituir false com showScore em nosso JSX:

<div className="app">{showScore ? <div className="score-section">// ... score section markup</div> : <>// ... quiz question/answer markup</>}</div>

Nada mudará, mas se mudarmos o valor do estado para verdadeiro, a pontuação div será exibida. Isso porque tudo está embrulhado em um ternário, ou seja:

“Se showScore for true, renderize a marcação da seção de pontuação, caso contrário, renderize a marcação de pergunta / resposta do questionário”

Agora, queremos atualizar esta variável de estado quando o usuário chegar ao final do questionário. Já escrevemos a lógica para isso em nossa função handleAnswerButtonClick.

Tudo o que precisamos fazer é substituir a lógica de alerta que atualiza o showScore variável a ser verdadeira:

if (nextQuestion < questions.length) {	setCurrentQuestion(nextQuestion);} else {	setShowScore(true);}

Se clicarmos nas respostas do questionário, ele mostrará a seção de pontuação quando chegarmos ao final. No momento, o texto e a partitura mostrados são uma string codificada, então devemos torná-la dinâmica.

Salvando a pontuação

Nossa próxima tarefa é manter uma pontuação em algum lugar em nosso aplicativo e incrementar esse valor se o usuário selecionar a opção correta.

O lugar lógico para fazer isso é na função “handleAnswerOptonClick”.

Lembre-se de quando iteramos sobre o answerOptions, a função de mapa nos dá um objeto para cada um que inclui o questionText, e um valor booleano mostrando se essa resposta está correta ou não. Esse booleano é o que usaremos para nos ajudar a aumentar nossa pontuação.

Em nosso botão, atualize a função assim:

onClick={()=> handleAnswerButtonClick(answerOption.isCorrect)

Em seguida, atualize a função para aceitar este parâmetro:

const handleAnswerButtonClick = (isCorrect) => {	//... other code};

Agora podemos adicionar alguma lógica aqui em nossa função. Por enquanto, queremos dizer “se isCorrect for verdadeiro, queremos mostrar um alerta”:

const handleAnswerButtonClick = (isCorrect) => {	if (isCorrect) {		alert(“the answer is correct!”)	}	//...other code};

Este é o mesmo que if(isCorrect === true), apenas uma versão abreviada. Agora, se tentarmos fazer isso, você verá que receberemos um alerta quando clicarmos na resposta correta.

Só para recapitular até agora:

  • Quando iteramos sobre os botões, passamos o isCorrect valor booleano desse botão para o handleAnswerButtonClick função
  • Na função verificamos se este valor é verdadeiro e mostramos um alerta se for verdadeiro.

Em seguida, queremos realmente salvar a partitura. Como você acha que fazemos isso? Se você disse valor de estado, está correto!

Vá em frente e adicione outro valor de estado chamado “pontuação”. Lembre-se de prefixar a função para alterar o valor com “set” para que seja setScore. Inicialize para 0:

const [score, setScore] = useState(0);

Em seguida, em vez de mostrar um alerta, queremos atualizar nossa pontuação em 1 se o usuário acertou a resposta.

Na nossa handleAnswerButtonClick função, remova o alerta e aumente nossa pontuação em um:

const handleAnswerButtonClick = (isCorrect) => {	if (answerOption.isCorrect) {		setScore(score + 1);	}	//...other code};

Mostrando a pontuação

Para mostrar a pontuação, só precisamos fazer uma pequena alteração em nosso código de renderização. Em nosso JSX, remova a string codificada na seção de pontuação e adicione esta nova variável:

<div className="score-section">	You scored {score} out of {questions.length}</div>
<div className="score-section">	You scored {score} out of {questions.length}</div>

Agora, se analisarmos as respostas, a pontuação é dinâmica e será exibida corretamente no final!

Uma última coisa antes de encerrarmos nosso aplicativo de teste: você notará que a pergunta atual exibida na IU é sempre “1”, já que está codificada. Precisamos mudar isso para ser mais dinâmico.

Substitua a “contagem de perguntas” pelo seguinte:

<div className="question-count">	<span>Question {currentQuestionIndex + 1}</span>/{questions.length}</div>

Lembre-se de que precisamos do +1 quando os computadores começarem a contar a partir de 0 e não de 1.

Quer mais ideias de projetos?

Por que não tentar construir alguns projetos React para impulsionar ainda mais seu aprendizado? Toda semana eu envio um novo projeto para você experimentar um exemplo prático, código inicial e dicas. Inscreva-se para receber isso diretamente na sua caixa de entrada!

[ad_2]

Fonte