Sådan oprettes en quiz-app ved hjælp af React - med tip og startkode

I denne nybegynder React-tutorial skal vi oprette en quiz-app. Vi arbejder med komplekse tilstandsobjekter, hvordan man håndterer forskellige tilstandskroge og gengiver ting baseret på tilstand.

Tjek det ud:

Prøv det selv

Hvis du først vil prøve selv, er her scenarierne (du kan også få fat i startkoden nedenfor):

  • Når brugeren klikker på en knap, skal det næste spørgsmål vises
  • Hvis brugeren får spørgsmålet korrekt, skal det øge deres score
  • Når brugeren kommer til slutningen af ​​quizzen, skal deres samlede score vises

Video gennemgang

Startkode

Grib det over på GitHub her.

Lad os gå!

Hvis du åbner startkoden og går til App.js , ser du, at jeg har givet dig en liste med spørgsmål / svar, gemt som en matrix kaldet spørgsmål . Dette er vores quiz.

Vores første mål er at tage spørgsmålsdataene fra arrayet og vise dem på skærmen.

Vi fjerner den hardkodede tekst og tager dataene fra det første spørgsmål for nu, bare for at få tingene i gang. Vi bekymrer os om at skifte spørgsmål senere.

Fjern i vores JSX den hardkodede spørgsmålstekst og skriv for {questions[0]}at få det første element (eller spørgsmål) i vores spørgsmålsarray.

 {questions[0]} 

Afgivelse af spørgsmål og svar

Det første spørgsmål er et objekt, så vi kan bruge "dot notation" for at få adgang til egenskaberne. Nu gør vi bare for {question[0].questionText}at få adgang til spørgsmålsteksten til dette objekt:

 {questions[0].questionText} 

Gem og kør appen. Læg mærke til, hvordan teksten opdateres. Husk, at vi bare tager den første spørgsmålstekst fra det første objekt i vores spørgsmålsarray.

Vi tager en lignende tilgang til svarmulighederne. Fjern de hardkodede knapper, så bruger vi kortfunktionen til at løbe over svarmulighederne for et givet spørgsmål.

Husk kortfunktionens sløjfer over matrixen og giver os det aktuelle element, som sløjfen er i øjeblikket i form af en variabel.

Erstat "svarafsnittet" div med følgende:

 {questions[0].answerOptions.map((answerOption, index) => ( {answerOption.answerText} ))} 

Gem og kør appen. Bemærk, hvordan fire svarsknapper vises, og teksten gengives dynamisk.

Lad os sammenfatte:

  • Vi får det første spørgsmål fra spørgsmålsarrayet: questions[0]
  • Det første spørgsmål er et objekt, der indeholder en matrix af answerOptions. Vi kan komme til dette array ved hjælp af punktnotation:questions[0].answerOptions
  • Da det answerOptionser en matrix, kan vi kortlægge dette:questions[0].answerOptions.map
  • Inde i kortfunktionen gengiver vi en knap for hver answerOptionog viser teksten

Ændring af spørgsmål ved hjælp af tilstand

Lad os nu gå tilbage til vores JSX. Bemærk hvordan hvis vi skifter questions[0]til questions[1]eller questions[2], at brugergrænsefladen opdateres. Dette skyldes, at det tager data fra forskellige spørgsmål i vores spørgsmål array, afhængigt af indekset.

Hvad vi vil gøre er at bruge et tilstandsobjekt til at holde, hvilket spørgsmål brugeren er i øjeblikket, og opdatere dette, når der klikkes på en svarsknap. Du kan se dette ved at køre koden i det sidste eksempel.

Gå videre og tilføj et tilstandsobjekt, der indeholder det aktuelle spørgsmålsnummer, som brugeren er på. Dette initialiseres til 0, så quizzen tager det første spørgsmål fra arrayet:

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

Nu vil vi erstatte den hardkodede '0' i vores JSX med denne variabel. Først til spørgsmålsteksten:

 {questions[currentQuestion].questionText} 

Og også til spørgsmålssektionen:

 {questions[currentQuestion].answerOptions.map((answerOption, index) => ( {answerOption.answerText} ))} 

Hvis du nu initialiserer det aktuelle spørgsmål til noget andet end 0, for eksempel 1 eller 2, opdateres brugergrænsefladen for at vise spørgsmålet og svarene på det pågældende spørgsmål. Temmelig sejt!

Lad os tilføje noget kode, så når vi klikker på et svar, øges den aktuelle spørgsmålsværdi for at tage os til det næste spørgsmål.

Opret en ny funktion kaldet handleAnswerButtonClick . Dette kaldes, når brugeren klikker på et svar.

Vi vil øge den aktuelle spørgsmålsværdi med en, gemme den i en ny variabel og sætte denne nye variabel i tilstand:

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

Næste tilføj en onClick-begivenhed til vores knap sådan:

 handleAnswerButtonClick()}>{answerOption.answerText} 

Hvis vi prøver dette, vil du se, at det fungerer, indtil vi kommer til slutningen:

Så hvad sker der? Nå i vores handleAnswerButtonClick- funktion øges tallet og sætter det til tilstand. Det er ok.

Men husk at vi bruger dette nummer til at få adgang til et array for at få spørgsmål og svarmuligheder. Når vi når til 5, vil den bryde, da der ikke er noget 5. element!

Lad os kontrollere, om vi ikke overskrider grænsen. Lad os tilføje følgende betingelse i vores handleAnswerButtonClick-funktion:

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

Dette siger grundlæggende, at hvis det næste spørgsmål nummer er mindre end det samlede antal spørgsmål, skal du opdatere tilstanden til det næste spørgsmål. Ellers har vi nået slutningen af ​​quizzen, så vis en advarsel for nu.

Viser scoreskærmen

I stedet for at vise en advarsel er det, vi vil gøre, at vise skærmbilledet "score".

Hvis vi ser på JSX, vil du bemærke, at jeg har lagt markeringen her for dig, vi skal bare erstatte "falsk" med logikken.

Så hvordan skal vi gøre det? Nå dette er en perfekt ting at sætte i stat!

Tilføj et andet tilstandsobjekt, der gemmer, hvorvidt vi vil vise scoreskærmen eller ej:

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

Og udskift falsemed showScorei vores JSX:

 {showScore ? // ... score section markup : // ... quiz question/answer markup} 

Intet vil ændre sig, men hvis vi ændrer tilstandsværdien til sand, vil score div vises. Dette skyldes, at alt er pakket ind i en ternær, hvilket betyder:

"Hvis showScore er sandt, skal du gengive markeringen af ​​scoreafsnittet, ellers skal du gengive quizspørgsmålet / svarmarkeringen"

Nu vil vi opdatere denne tilstandsvariabel, når brugeren har nået slutningen af ​​quizzen. Vi har allerede skrevet logikken for dette i vores handleAnswerButtonClick-funktion.

Alt hvad vi skal gøre er at erstatte alarmlogikken, der opdaterer showScore- variablen til at være sand:

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

Hvis vi klikker gennem svarene på quizzen, viser det scoreafsnittet, når vi kommer til slutningen. I øjeblikket er den viste tekst og score en strengkodet streng, så vi skal gøre den dynamisk.

Gemmer scoren

Vores næste opgave er at holde en score et eller andet sted i vores app og øge denne værdi, hvis brugeren vælger den rigtige mulighed.

Det logiske sted at gøre dette ligger inden for “handleAnswerOptonClick” -funktionen.

Husk, at når vi gentager svaret Options , giver kortfunktionen os et objekt for hver, der inkluderer spørgsmålsteksten og en boolsk værdi, der viser, om svaret er korrekt eller ej. Denne booleske er det, vi vil bruge til at hjælpe os med at øge vores score.

I vores knap skal du opdatere funktionen sådan:

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

Opdater derefter funktionen for at acceptere denne parameter:

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

Nu kan vi tilføje nogle logik her i vores funktion. For nu vil vi sige "hvis isCorrect er sandt, vil vi vise en advarsel":

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

Dette er det samme som if(isCorrect === true)bare en stenografisk version. Hvis vi nu prøver dette, vil du se, at vi får en advarsel, når vi klikker på det rigtige svar.

Bare for at opsummere indtil videre:

  • Når vi gentager knapperne, videregiver vi den isCorrectboolske værdi for den pågældende knap til handlenAnswerButtonClick- funktionen
  • I funktionen kontrollerer vi, om denne værdi er sand, og viser en alarm, hvis den er.

Dernæst vil vi faktisk gemme scoren. Hvordan tror du, vi gør dette? Hvis du sagde tilstandsværdi, er du korrekt!

Gå videre og tilføj en anden tilstandsværdi kaldet "score". Husk at foretage forud for funktionen for at ændre værdien med "sæt", så den bliver indstillet. Initialiser det til 0:

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

Næste i stedet for at vise en advarsel, vil vi opdatere vores score med 1, hvis brugeren fik svaret korrekt.

I vores handleAnswerButtonClick- funktion skal du fjerne alarmen og øge vores score med en:

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

Viser partituret

For at vise resultatet er vi bare nødt til at foretage en lille ændring af vores gengivelseskode. I vores JSX skal du fjerne den hårdkodede streng i sektionen score og tilføje denne nye variabel:

 You scored {score} out of {questions.length} 
 You scored {score} out of {questions.length} 

Hvis vi nu løber gennem svarene, er resultatet dynamisk og vises korrekt i slutningen!

En sidste ting inden vi afslutter vores quiz-app: du vil bemærke, at det aktuelle spørgsmål, der vises i brugergrænsefladen, altid er "1", da det er hardkodet. Vi er nødt til at ændre dette for at være mere dynamisk.

Udskift "antal spørgsmål" med følgende:

 Question {currentQuestionIndex + 1}/{questions.length} 

Husk, at vi har brug for +1, da computere begynder at tælle fra 0 og ikke 1.

Vil du have flere projektidéer?

Hvorfor ikke prøve at opbygge nogle React-projekter for at øge din læring endnu mere? Hver uge sender jeg et nyt projekt ud til dig for at prøve et fungerende eksempel, startkode og tip. Abonner for at få dette direkte til din indbakke!