În acest tutorial pentru începători React, vom construi o aplicație de testare. Vom lucra cu obiecte complexe de stare, cum să gestionăm diferite cârlige de stare și să redăm lucrurile în funcție de stare.

Verifică:

Cum sa construiti o aplicatie de testare utilizand React

Incearca-l tu insuti

Dacă doriți să vă încercați mai întâi, iată scenariile (puteți lua și codul de start mai jos):

  • Când utilizatorul face clic pe un buton, ar trebui să apară următoarea întrebare
  • Dacă utilizatorul obține întrebarea corectă, ar trebui să-și mărească scorul
  • Când utilizatorul ajunge la sfârșitul testului, ar trebui să fie afișat scorul total

Descărcare video

Cod de pornire

Prindeți-l la GitHub aici.

Sa mergem!

Dacă deschideți codul de pornire și accesați App.js, veți vedea că v-am dat o listă de întrebări / răspunsuri, stocate ca o matrice numită întrebări. Acesta este testul nostru.

Primul nostru obiectiv este să preluăm datele întrebărilor din matrice și să le afișăm pe ecran.

Vom elimina textul codificat și vom prelua datele de la prima întrebare deocamdată, doar pentru a începe lucrurile. Ne vom face griji cu privire la schimbarea întrebărilor mai târziu.

În JSX, eliminați textul și tastați întrebarea codificată {questions[0]} pentru a obține primul articol (sau întrebare) din matricea noastră de întrebări.

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

Redarea întrebării și a răspunsurilor

Prima întrebare este un obiect, deci putem folosi „notația punctelor” pentru a obține acces la proprietăți. Acum o vom face {question[0].questionText} pentru a obține acces la textul întrebării pentru acest obiect:

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

Salvați și rulați aplicația. Observați cum se actualizează textul. Amintiți-vă că luăm textul primei întrebări din primul obiect din matricea noastră de întrebări.

Vom adopta o abordare similară cu opțiunile de răspuns. Eliminați butoanele codificate și vom folosi funcția de hartă pentru a trece peste opțiunile de răspuns pentru o anumită întrebare.

Amintiți-vă că funcția de hartă se bucură peste matrice și ne oferă elementul curent la care se află bucla în prezent, sub forma unei variabile.

Înlocuiți div-ul „secțiunea de răspuns” cu următorul:

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

Salvați și rulați aplicația. Observați cum apar patru butoane de răspuns și textul este redat dinamic.

Să recapitulăm:

  • Primim prima întrebare din matricea de întrebări: questions[0]
  • Prima întrebare este un obiect, care conține o serie de answerOptions. Putem ajunge la această matrice folosind notația punct: questions[0].answerOptions
  • Pentru că answerOptions este o matrice, putem face maparea peste aceasta: questions[0].answerOptions.map
  • În interiorul funcției de hartă, redăm un buton pentru fiecare answerOptionși afișați textul

Modificarea întrebărilor folosind starea

Acum să revenim în JSX-ul nostru. Observați cum, dacă ne schimbăm questions[0] la questions[1], sau questions[2], UI se va actualiza. Acest lucru se datorează faptului că preluează datele din diferite întrebări din matricea noastră de întrebări, în funcție de index.

Ceea ce vrem să facem este să folosim un obiect de stare pentru a menține întrebarea pe care se află utilizatorul în prezent și să actualizăm acest lucru când se face clic pe butonul de răspuns. Puteți vedea acest lucru din rularea codului în exemplul final.

Mergeți mai departe și adăugați un obiect de stare, care va reține numărul întrebării curente utilizatorul este pornit. Acest lucru va fi inițializat la 0, astfel încât testul ia prima întrebare din matrice:

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

Acum vrem să înlocuim codul hard „0” din JSX cu această variabilă. Mai întâi pentru textul întrebării:

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

Și, de asemenea, pentru secțiunea de întrebări:

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

Acum, dacă inițializați Întrebare curentă la altceva decât 0, de exemplu 1 sau 2, interfața de utilizare se va actualiza pentru a afișa întrebarea și răspunsurile pentru acea întrebare. Destul de la moda!

Să adăugăm un cod, astfel încât, atunci când facem clic pe un răspuns, să incrementăm Întrebare curentă valoare pentru a ne duce la următoarea întrebare.

Creați o nouă funcție numită handleAnswerButtonClick. Așa se va apela atunci când utilizatorul dă clic pe un răspuns.

Vom incrementa valoarea întrebării curente cu una, o vom salva într-o nouă variabilă și vom seta această nouă variabilă în stare:

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

Apoi adăugați un eveniment onClick la butonul nostru astfel:

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

Dacă încercăm acest lucru, veți vedea că funcționează, până ajungem la final:

Cum sa construiti o aplicatie de testare utilizand React.webp

Deci, ce se întâmplă? Ei bine în al nostru handleAnswerButtonClick funcție, incrementăm numărul și îl setăm la stare. Asta e ok.

Dar amintiți-vă că folosim acest număr pentru a accesa o matrice, pentru a obține opțiunile de întrebare și răspuns. Odată ce ajungem la 5, se va sparge deoarece nu există nici un al 5-lea element!

Să facem o verificare pentru a ne asigura că nu depășim limita. În funcția noastră handleAnswerButtonClick să adăugăm următoarea condiție:

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

Aceasta spune practic dacă numărul următoarei întrebări este mai mic decât numărul total de întrebări, actualizați starea la următoarea întrebare. Altfel, am ajuns la finalul testului, așa că afișați o alertă pentru moment.

Se afișează ecranul de scor

În loc să afișăm o alertă, ceea ce vrem să facem este să afișăm ecranul „scor”.

Dacă ne uităm la JSX, veți observa că am introdus marcajul aici pentru dvs., trebuie doar să înlocuim „fals” cu logica.

Deci, cum putem face asta? Ei bine, acesta este un lucru perfect pentru a pune în stare!

Adăugați un alt obiect de stare care va stoca dacă dorim sau nu să afișăm ecranul de scor:

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

Și înlocuiți false cu showScore în JSX-ul nostru:

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

Nimic nu se va schimba, dar dacă schimbăm valoarea stării în adevărat, atunci se va afișa scorul div. Acest lucru se datorează faptului că totul este înfășurat într-un ternar, adică:

„Dacă showScore este adevărat, redați marcajul secțiunii de scor, altfel, redați marcajul întrebării / răspunsului la test”

Acum, dorim să actualizăm această variabilă de stare când utilizatorul a ajuns la sfârșitul testului. Am scris deja logica pentru aceasta în funcția noastră handleAnswerButtonClick.

Tot ce trebuie să facem este să înlocuim logica de alertă care actualizează fișierul showScore variabilă pentru a fi adevărat:

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

Dacă facem clic pe răspunsurile la test, acesta va afișa secțiunea de scor când ajungem la final. În acest moment, textul și scorul afișat sunt un șir codat, deci ar trebui să îl dinamizăm.

Salvarea scorului

Următoarea noastră sarcină este de a ține un scor undeva în aplicația noastră și de a crește această valoare dacă utilizatorul selectează opțiunea corectă.

Locul logic pentru a face acest lucru este în cadrul funcției „handleAnswerOptonClick”.

Amintiți-vă când vom itera peste răspuns Opțiuni, funcția hartă ne oferă un obiect pentru fiecare care include întrebareText, și a valoare booleană arătând dacă acel răspuns este corect sau nu. Acest boolean este ceea ce vom folosi pentru a ne ajuta să ne creștem scorul.

În butonul nostru, actualizați funcția astfel:

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

Următoarea actualizare a funcției pentru a accepta acest parametru:

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

Acum putem adăuga unele logici aici în funcția noastră. Deocamdată vrem să spunem „dacă isCorrect este adevărat, vrem să afișăm o alertă”:

const handleAnswerButtonClick = (isCorrect) => {
	if (isCorrect) {
		alert(“the answer is correct!”)
	}

	//...other code
};

Aceasta este la fel ca if(isCorrect === true), doar o versiune stenogramă. Acum, dacă încercăm acest lucru, veți vedea că vom primi o alertă atunci când facem clic pe răspunsul corect.

Doar pentru a recapitula până acum:

  • Când iterăm peste butoane, trecem isCorrect valoare booleană pentru acel buton la handleAnswerButtonClick funcţie
  • În funcție verificăm dacă această valoare este adevărată și afișăm o alertă dacă este.

Apoi vrem să salvăm efectiv scorul. Cum crezi că facem asta? Dacă ai spus valoarea de stat ai dreptate!

Continuați și adăugați o altă valoare de stare numită „scor”. Nu uitați să prefixați funcția pentru a schimba valoarea cu „set”, astfel încât să fie setScore. Inițializați-l la 0:

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

Apoi, în loc să afișăm o alertă, dorim să ne actualizăm scorul cu 1 dacă utilizatorul a primit răspunsul corect.

În a noastră handleAnswerButtonClick funcție, eliminați alerta și creșteți scorul nostru cu unul:

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

	//...other code
};

Arătând scorul

Pentru a arăta scorul trebuie doar să facem o mică modificare a codului nostru de redare. În JSX, eliminați șirul codat în secțiunea de scor și adăugați această nouă variabilă:

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

Acum, dacă trecem prin răspunsuri, scorul este dinamic și se va afișa corect la final!

Un ultim lucru înainte de a încheia aplicația de testare: veți observa că întrebarea curentă afișată în interfața de utilizare este întotdeauna „1”, deoarece este codificată hard. Trebuie să schimbăm acest lucru pentru a fi mai dinamici.

Înlocuiți „numărul de întrebări” cu următoarele:

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

Amintiți-vă că avem nevoie de +1 deoarece computerele încep să numere de la 0 și nu de la 1.

Vrei mai multe idei de proiecte?

De ce nu încercați să construiți câteva proiecte React pentru a vă stimula și mai mult învățarea? În fiecare săptămână vă trimit un nou proiect pentru a încerca un exemplu de lucru, un cod de pornire și sfaturi. Abonați-vă pentru a primi acest lucru direct în căsuța de e-mail