Introductie tot Immer
Deze pagina is vertaald door PageTurner AI (beta). Niet officieel goedgekeurd door het project. Een fout gevonden? Probleem melden →
Immer
Immer (Duits voor: altijd) is een klein pakket waarmee je op een handigere manier kunt werken met onveranderlijke state.
Immer is levensveranderend als JS-ontwikkelaar, en ik overdrijf niet :) Het staat echt op hetzelfde niveau als Prettier in termen van "wauw, dit pakket is geweldig, hoe heb ik ooit zonder kunnen leven?" --Mark Erikson, (de) Redux Maintainer, @replayio
Winnaar van de "Doorbraak van het jaar" React open source award en "Meest impactvolle bijdrage" JavaScript open source award in 2019.
Introductieblog: Immer: Onveranderlijkheid op de makkelijke manier
Korte Egghead.io-les over de essentie van Immer: Vereenvoudig het maken van onveranderlijke databomen met Immer (7m)
Gratis diepgaande Egghead.io-cursus: Onveranderlijke JavaScript-datastructuren met Immer (58m)
Immer vereenvoudigt het omgaan met onveranderlijke datastructuren​
Immer kan worden gebruikt in elke context waar onveranderlijke datastructuren nodig zijn, zoals in combinatie met React-state, React- of Redux-reducers of configuratiebeheer. Onveranderlijke datastructuren maken efficiënte wijzigingsdetectie mogelijk: als de referentie naar een object niet is veranderd, is het object zelf niet gewijzigd. Bovendien maakt het klonen relatief goedkoop: ongewijzigde delen van een databoom hoeven niet te worden gekopieerd en worden in het geheugen gedeeld met oudere versies van dezelfde state.
Over het algemeen kunnen deze voordelen worden bereikt door ervoor te zorgen dat je nooit een eigenschap van een object, array of map wijzigt, maar altijd een aangepaste kopie maakt. In de praktijk kan dit resulteren in behoorlijk omslachtige code, en het is gemakkelijk om per ongeluk deze beperkingen te overtreden. Immer helpt je om het onveranderlijke dataparadigma te volgen door deze pijnpunten aan te pakken:
Immer detecteert per ongeluk aangebrachte mutaties en gooit een fout.
Immer elimineert de noodzaak voor typische boilerplate-code die nodig is bij het maken van diepe updates voor onveranderlijke objecten: Zonder Immer moeten objectkopieën handmatig op elk niveau worden gemaakt, meestal met veel
...spread-operaties. Met Immer worden wijzigingen aangebracht in eendraft-object dat de wijzigingen vastlegt en zorgt voor het maken van de nodige kopieën, zonder ooit het originele object te beïnvloeden.Met Immer hoef je geen specifieke API's of datastructuren te leren om van het paradigma te profiteren. Met Immer gebruik je gewone JavaScript-datastructuren en de bekende mutabele JavaScript-API's, maar dan veilig.
Een snel voorbeeld ter vergelijking​
const baseState = [
{
title: "Learn TypeScript",
done: true
},
{
title: "Try Immer",
done: false
}
]
Stel dat we de bovenstaande basisstate hebben en we moeten de tweede todo bijwerken en een derde toevoegen. We willen echter het originele baseState niet muteren en ook diep klonen vermijden (om de eerste todo te behouden).
Zonder Immer​
Zonder Immer moeten we zorgvuldig elk niveau van de statestructuur dat door onze wijziging wordt beïnvloed, ondiep kopiëren:
const nextState = baseState.slice() // shallow clone the array
nextState[1] = {
// replace element 1...
...nextState[1], // with a shallow clone of element 1
done: true // ...combined with the desired update
}
// since nextState was freshly cloned, using push is safe here,
// but doing the same thing at any arbitrary time in the future would
// violate the immutability principles and introduce a bug!
nextState.push({title: "Tweet about it"})
Met Immer​
Met Immer is dit proces eenvoudiger. We kunnen de produce-functie gebruiken, die als eerste argument de begintoestand accepteert en als tweede argument een functie (de recipe) die een draft ontvangt waarop we directe mutaties kunnen toepassen. Deze mutaties worden vastgelegd en gebruikt om de volgende staat te genereren zodra de recipe klaar is. produce regelt alle benodigde kopieën en beschermt tegen toekomstige per ongeluk aanpassingen door de data te bevriezen.
import {produce} from "immer"
const nextState = produce(baseState, draft => {
draft[1].done = true
draft.push({title: "Tweet about it"})
})
Zoek je Immer in combinatie met React? Sla gerust over naar de React + Immer-pagina.
Hoe Immer werkt​
Het basisidee is dat je met Immer al je wijzigingen aanbrengt op een tijdelijke draft, die een proxy is van de currentState. Zodra alle mutaties klaar zijn, genereert Immer de nextState op basis van de wijzigingen aan de draft. Dit betekent dat je kunt werken met je data door deze simpelweg aan te passen, terwijl je alle voordelen van onveranderlijke data behoudt.

Werken met Immer is als een persoonlijke assistent hebben. De assistent neemt een brief (de huidige staat) en geeft je een kladversie (draft) om wijzigingen op aan te brengen. Als je klaar bent, neemt de assistent je kladversie en maakt daar de echte onveranderlijke eindversie van (de volgende staat).
Ga naar het volgende hoofdstuk om dieper in te gaan op produce.
Voordelen​
Volg het onveranderlijk dataparadigma terwijl je gewone JavaScript-objecten, arrays, Sets en Maps gebruikt. Geen nieuwe API's of "mutatiepatronen" om te leren!
Sterk getypeerd, geen op tekst gebaseerde padselectors etc.
Structureel delen out-of-the-box
Objectbevriezing out-of-the-box
Diepe updates zijn een fluitje van een cent
Minder boilerplate. Minder ruis, beknoptere code.
Eersteklas ondersteuning voor JSON-patches
Klein: 3KB ingepakt (gzipped)