Immutable

Once we've created it and it never changes

Why Immutable ?

Functional programming (FP)

  • rejecting side-effects

  • avoiding shared state, mutable data
    • eg.

      Array.prototype.filter()

      Array.prototype.map()

      ...

when you refuse to mutate objects, you have to create a whole new object ( deep clone )

each time something changes

  • slow things down
  • eat up memory
  • making functional programming seem inefficient

But

比如:

🐂 🐑 🐶 🐱 🐰 🐒

0

1

2

3

4

🐂 👽 🐶 🐱 🐰 🐒

0

1

2

3

4

5

5

How?

好的

数据结构

可以解决80%的问题

persistent data structures

🐂 🐑

0

1

2

3

4

🐶 🐱
🐰 🐒

5

🐂 👽

0

1

Library

German for: always

  • tiny   - 4kb
  • no new API to learn

  • Automatically freezes

API:

produce(currentState, producer: (draftState) => void): nextState
import produce from "immer"

const baseState = [
    {
        todo: "Learn typescript",
        done: true
    },
    {
        todo: "Try immer",
        done: false
    }
]

const nextState = produce(baseState, draftState => {
    draftState.push({ todo: "Tweet about it" })
    draftState[1].done = true
})

console.log(nextState.length, baseState.length) // 3 2

console.log(baseState === nextState)  // false


console.log(baseState[0] === nextState[0]) // true , because not change
console.log(baseState[1] === nextState[1]) // false , because change 

show case

Currying

// mapper will be of signature (state, index) => state

const mapper = produce((draft, index) => {
    draft.index = index
})

// example usage

console.dir([{}, {}, {}].map(mapper)) // [{index: 0}, {index: 1}, {index: 2}])

In React

/**
 * Classic React.setState with a deep merge
 */
onBirthDayClick1 = () => {
    this.setState(prevState => ({
        user: {
            ...prevState.user,
            age: prevState.user.age + 1
        }
    }))
}

/**
 * ...But, since setState accepts functions,
 * we can just create a curried producer and further simplify!
 */
onBirthDayClick2 = () => {
    this.setState(
        produce(draft => {
            draft.user.age += 1
        })
    )
}

setState can accept function!

How does Immer work?

No proxies?

  • Microsoft Internet Explorer
  • React Native (< v0.59) on Android

Immer will fallback to an ES5 compatible implementation

Object.defineProperty()
  • blibee-exam

 

  • blibee-yferp

 

。。。

In our project:

Done

Immeutate

By bin lv