React: use-immer 让复杂数据变得简单

165 阅读1分钟

前情概要

本文不打算过多讲述Immer原理,喜欢深究的小伙伴可以参考这篇文章 immer原理

举一个简单例子

const initialUser = {
  "id": 1,
  "name": "Leanne Graham",
  "username": "Bret",
  "email": "Sincere@april.biz",
  "address": {
    "street": "Kulas Light",
    "suite": "Apt. 556",
    "city": "Gwenborough",
    "zipcode": "92998-3874",
    "geo": {
      "lat": "-37.3159",
      "lng": "81.1496"
    }
  },
  "phone": "1-770-736-8031 x56442",
  "website": "hildegard.org",
  "company": {
    "name": "Romaguera-Crona",
    "catchPhrase": "Multi-layered client-server neural-net",
    "bs": "harness real-time e-markets"
  }
};

function User() {
  const [user, setUser] = useState(initialUser);

  return (
    <div>
      <label>修改 user.address.geo.lat </label>
      <input
        value={user.address.geo.lat}
        onChange={e => {
          setUser({
            ...user,
            address: {
              ...user.address,
              geo: {
                ...user.address.geo,
                lat: e.target.value
              }
            }
          })
        }}
      />
    </div>
  )
}

如果你的 state 嵌套很深,您可能需要考虑将其扁平化,但是如果你不想更改 state 的结构,更喜欢使用嵌套扩展的快捷方式。当你修改一个复杂结构对象的某一属性的状态时,需要重复使用三点运算扩展符把其他属性平铺,作为一个学过使用过vue的码农,这能忍???

import { useImmer } from 'use-immer';

const [data, setData] = useImmer({
    "id": 1,
    "name": "Leanne Graham",
    "username": "Bret",
    "email": "Sincere@april.biz",
    "address": {
      "street": "Kulas Light",
      "suite": "Apt. 556",
      "city": "Gwenborough",
      "zipcode": "92998-3874",
      "geo": {
        "lat": "-37.3159",
        "lng": "81.1496"
      }
    },
    "phone": "1-770-736-8031 x56442",
    "website": "hildegard.org",
    "company": {
      "name": "Romaguera-Crona",
      "catchPhrase": "Multi-layered client-server neural-net",
      "bs": "harness real-time e-markets"
    }
});

//添加一项
setData(draft => {
  draft.name = 'John';
});

//减少count
setData(draft => {
  draft.company.name = 'Romaguera';
});   

工作原理

简单来讲跟vue3的双向绑定底层原理一样,使用了Proxy API 代理了对象和数组,文笔太差描述不到位,喜欢深究的可借鉴 immer源码解读