Hur kan du övertyga React om att två användningar av en komponent behöver ett eget individuellt tillstånd? Med nycklar såklart!

React-metoden kan vara ganska komplicerad, och du kan stöta på oväntat beteende eller till och med subtila buggar. Att bli av med sådana buggar kan vara ganska svårt om du inte är bekant med deras orsak.

En speciell bugg uppstår när du villkorligt renderar samma komponent med olika egenskaper. Utforska denna bugg i detalj och ta reda på hur du använder React-nycklar för att lösa det.

React-komponenter är inte alltid oberoende

Dess enkla syntax är en av huvudorsakerna du borde lära dig React. Men trots många fördelar är ramverket inte utan buggar.

Felet du kommer att lära dig om här uppstår när du villkorligt renderar samma komponent, men skickar olika rekvisita till den.

I sådana här fall kommer React att anta att de två komponenterna är desamma, så det kommer inte att bry sig om att rendera den andra komponenten. Som ett resultat kommer alla tillstånd du definierar i den första komponenten att bestå mellan renderingarna.

För att demonstrera, ta det här exemplet. Först har du följande Disken komponent:

import { useState, useEffect } from"react"

exportfunctionCounter({name}) {
const [count, setCount] = useState(0)

return(


{name}</div>

Detta Disken komponent accepterar en namn från föräldern via objektdestrukturering, vilket är ett sätt att använd rekvisita i React. Sedan återger den namnet i en. Den returnerar också två knappar: en för att minska räkna i tillstånd och den andra för att öka den.

Tänk på att det inte är något fel på ovanstående kod. Felet kommer från följande kodblock (App-komponenten), som använder räknaren:

import { useState } from"react"
import { Counter } from"./Counter"

exportdefaultfunctionApp() {
const [isKingsley, setIsKingsley] = useState(true)

return(


{ isKingsley? <Countername="Kingsley" />: <Countername="Sally" /> }


Som standard återger koden ovan räknaren med namnet Kingsley. Om du ökar räknaren till fem och klickar på Byta knappen, kommer den att återge den andra räknaren som heter Sally.

Men problemet är att räknaren inte kommer att återställas till standardläget noll efter att du har bytt dem.

Denna bugg uppstår eftersom båda tillstånden återger samma element i samma ordning. React vet inte att "Kingsley"-räknaren skiljer sig från "Sally"-räknaren. Den enda skillnaden är i namn prop men tyvärr använder React inte det för att skilja element åt.

Du kan komma runt detta problem på två sätt. Den första är genom att ändra din DOM och göra de två träden olika. Detta kräver att du förstår vad DOM är. Du kan till exempel slå in den första disken inuti en element och den andra inuti en element:

import { useState } from"react"
import { Counter } from"./Counter"

exportdefaultfunctionApp() {
const [isKingsley, setIsKingsley] = useState(true)

return (


{ isKingsley?
(<div>
"Kingsley" />
</div>)
:
(<section>
"Sally" />
</section>)
}


Om du ökar "Kingsley"-räknaren och klickar Byta, återställs tillståndet till 0. Återigen, detta händer eftersom strukturen för de två DOM-träden är olika.

När är Kingsley variabel är Sann, kommer strukturen att vara div >div > Disken (en div som innehåller en div, som innehåller en räknare). När du byter räknartillstånd med knappen blir strukturen div > sektion > Disken. På grund av denna diskrepans kommer React automatiskt att återge en ny räknare med ett återställningstillstånd.

Du kanske inte alltid vill ändra strukturen för din markering så här. Det andra sättet att lösa denna bugg undviker behovet av annan uppmärkning.

Använda nycklar för att rendera en ny komponent

Nycklar gör att React kan skilja mellan element under renderingsprocessen. Så om du har två element som är exakt lika, och du vill signalera till React att det ena skiljer sig från det andra, måste du ställa in ett unikt nyckelattribut för varje element.

Lägg till en nyckel till varje räknare, så här:

import { useState } from"react"
import { Counter } from"./Counter"

exportdefaultfunctionApp() {
const [isKingsley, setIsKingsley] = useState(true)

return(


{ isKingsley?
"Kingsley" name="Kingsley" />:
"Sally" name="Sally" />
}


Nu, när du ökar "Kingsley"-räknaren och klickar Byta, React återger en ny räknare och nollställer tillståndet.

Du bör också använda nycklar när du renderar en rad objekt av samma typ, eftersom React inte vet skillnaden mellan varje objekt.

exportdefaultfunctionApp() {
const names = ["Kingsley", "John", "Ahmed"]

return(


{ names.map((name, index) => {
return<Counterkey={index}name={name} />
})}
</div>
)
}

När du tilldelar nycklar kommer React att associera en separat räknare till varje objekt. På så sätt kan den återspegla alla ändringar du gör i arrayen.

Ytterligare ett fall för avancerad nyckelanvändning

Du kan också använda nycklar för att associera ett element med ett annat element. Till exempel kanske du vill associera ett indataelement med olika element beroende på värdet på en tillståndsvariabel.

För att demonstrera, justera appkomponenten:

import { useState } from"react"

exportdefaultfunctionApp() {
const [isKingsley, setIsKingsley] = useState(true)

return(


{ isKingsley? <div>Kingsley's Scorediv>: <div>Sally's scorediv> }
"Kingsley": "Sally" } type="number"/>


Nu, varje gång du byter mellan element för Kingsley och Sally, ändrar du automatiskt din inputs nyckelattribut mellan "Kingsley" och "Sally". Detta kommer att tvinga React att helt återrendera inmatningselementet med varje klick på knappen.

Fler tips för att optimera React-applikationer

Kodoptimering är nyckeln till att skapa en trevlig användarupplevelse i din webb- eller mobilapp. Att känna till olika optimeringstekniker kan hjälpa dig att få ut det mesta av dina React-applikationer.

Det bästa är att du kan tillämpa de flesta av dessa optimeringstekniker med React Native-applikationer också.