Valkuilen
Deze pagina is vertaald door PageTurner AI (beta). Niet officieel goedgekeurd door het project. Een fout gevonden? Probleem melden →
Performancetips
Voor performancetips, zie Performancetips.
Herwijs het recipe-argument niet opnieuw toe
Wijs het draft-argument nooit opnieuw toe (bijvoorbeeld: draft = myCoolNewState). Pas in plaats daarvan de draft aan of geef een nieuwe staat terug. Zie Gegevens teruggeven van producers.
Immer ondersteunt alleen unidirectionele bomen
Immer gaat ervan uit dat je staat een unidirectionele boomstructuur is. Dat betekent: geen object mag twee keer voorkomen in de boom, er mogen geen circulaire referenties zijn. Er moet precies één pad zijn van de wortel naar elk knooppunt in de boom.
Geef nooit expliciet undefined terug vanuit een producer
Het is mogelijk om waarden terug te geven vanuit producers, maar het retourneren van undefined werkt niet omdat dit niet te onderscheiden is van helemaal geen aanpassing aan de draft! Als je de draft wilt vervangen door undefined, geef dan nothing terug vanuit de producer.
Pas exotische objecten niet aan
Immer ondersteunt geen exotische objecten zoals window.location.
Klassen moeten draftable gemaakt worden of onaangepast blijven
Je moet je eigen klassen geschikt maken om correct met Immer te werken. Voor documentatie hierover, zie het hoofdstuk over werken met complexe objecten.
Alleen geldige indices en lengte kunnen worden aangepast bij arrays
Voor arrays kunnen alleen numerieke eigenschappen en de length-eigenschap worden aangepast. Aangepaste eigenschappen worden niet bewaard bij arrays.
Gegevens die niet uit de staat komen worden nooit gedraft
Let op: gegevens die uit de closure komen, en niet uit de basisstaat, worden nooit gedraft, zelfs niet wanneer deze gegevens onderdeel zijn geworden van de nieuwe draft.
function onReceiveTodo(todo) {
const nextTodos = produce(todos, draft => {
draft.todos[todo.id] = todo
// Note, because 'todo' is coming from external, and not from the 'draft',
// it isn't draft so the following modification affects the original todo!
draft.todos[todo.id].done = true
// The reason for this, is that it means that the behavior of the 2 lines above
// is equivalent to code, making this whole process more consistent
todo.done = true
draft.todos[todo.id] = todo
})
}
Immer-patches zijn niet per se optimaal
De set patches gegenereerd door Immer zou correct moeten zijn, wat betekent dat toepassen op een gelijk basisobject tot dezelfde eindstaat moet leiden. Immer garandeert echter niet dat de gegenereerde set patches optimaal is, ofwel de minimaal mogelijke set patches.
Gebruik altijd het resultaat van geneste producers
Geneste produce-aanroepen worden ondersteund, maar merk op dat produce altijd een nieuwe staat produceert. Dus zelfs als je een draft doorgeeft aan een geneste produce, zijn de wijzigingen van de innerlijke produce niet zichtbaar in de draft van de buitenste produce; die wijzigingen zijn alleen zichtbaar in de output die de innerlijke produce teruggeeft. Met andere woorden: bij geneste produce krijg je een draft van een draft en het resultaat van de innerlijke produce moet terug worden samengevoegd in de originele draft (of geretourneerd). Bijvoorbeeld produce(state, draft => { produce(draft.user, userDraft => { userDraft.name += "!" })}) werkt niet omdat de output van de innerlijke produce niet wordt gebruikt. De correcte manier om geneste producers te gebruiken is:
produce(state, draft => {
draft.user = produce(draft.user, userDraft => {
userDraft.name += "!"
})
})
Drafts zijn niet referentieel gelijk
Draft-objecten in Immer zijn verpakt in een Proxy, dus je kunt == of === niet gebruiken om gelijkheid te testen tussen een origineel object en zijn equivalente draft (bijvoorbeeld bij het matchen van een specifiek element in een array). In plaats daarvan kun je de original-helper gebruiken:
const remove = produce((list, element) => {
const index = list.indexOf(element) // this won't work!
const index = original(list).indexOf(element) // do this instead
if (index > -1) list.splice(index, 1)
})
const values = [a, b, c]
remove(values, a)
Waar mogelijk is het aanbevolen om de vergelijking buiten de produce-functie uit te voeren, of om een unieke identifier-eigenschap zoals .id te gebruiken, om het gebruik van original te vermijden.
Array Methods Plugin: Callbacks ontvangen basiswaarden
Bij gebruik van de Array Methods Plugin (enableArrayMethods()), ontvangen callbacks voor overschreven methoden zoals filter, find, some, every en slice basiswaarden (geen drafts). Dit is de kernoptimalisatie voor prestaties - het voorkomt het aanmaken van proxies voor elk element tijdens iteratie.
import {enableArrayMethods, produce} from "immer"
enableArrayMethods()
produce(state, draft => {
draft.items.filter(item => {
// `item` is a base value here, NOT a draft
// Reading works fine:
return item.value > 10
// But direct mutation here won't be tracked:
// item.value = 999 // ❌ Won't affect the draft!
})
// Instead, use the returned result (which contains drafts):
const filtered = draft.items.filter(item => item.value > 10)
filtered[0].value = 999 // ✅ This works - filtered[0] is a draft
})
Dit geldt alleen voor methoden die door de plugin worden onderschept. Methoden zoals map, forEach en reduce worden NIET overschreven en werken normaal - hun callbacks ontvangen drafts.