immer——不可變對象操作的利器

一、什麼是immer

immer是一個用於JavaScript的不可變數據結構庫。不可變數據結構一旦創建就不能被修改,這意味著它們是永久存儲的,並且可以安全地在多個線程之間共享。immer允許您使用基於修改的代碼來構建不可變數據,但是在執行時會產生新數據,使其不可變。

二、immer的優勢

immer的一個優勢是,您可以在單個語句中創建具有多個層次的對象(例如,嵌套數組和對象)的不可變副本。使用immer可以輕鬆地將對象轉換為不可變的數據結構,並且不太容易出現錯誤。另一個優勢是immer使用ES6的Proxy,在JavaScript運行時捕獲對對象(或數組)的修改,進而生成新的不可變對象,讓您不必自己編寫複雜的邏輯來跟蹤變化。

三、immer的API使用

1. produce函數

immer的API核心是produce函數,該函數的原型如下:

produce(base: T, recipe: (draft: Draft) => (T | void)) => T

其中,base參數代表您要創建不可變對象的初始對象,recipe參數是一個函數,該函數接受當前初始對象dref的代理和對dref的修改。這個函數需要返回一個描述對dref的修改的函數。

下面是一個調用produce函數構建不可變對象的示例:

import produce from 'immer';

const baseState = [
  {
    todo: 'Learn typescript!',
    done: true
  },
  {
    todo: 'Use immer!',
    done: false
  }
]

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

2. Draft類型

Draft類型是immer中的一種數據類型。該類型對應於使用Proxy創建的可變副本。Draft類型有以下幾種內建API:

  • draft.someKey——訪問對象的屬性
  • delete draft.someKey——從對象中刪除一個屬性
  • draft.someArray.push(item)——對數組進行修改
  • draft.someArray[index] = item——對數組進行修改
  • draft.someArray.splice(index, removeCount, item1, item2, …)——對數組進行修改

3. produceWithPatches函數

produceWithPatches函數的工作方式類似於produce,唯一的區別是它返回一個元組,其中包含結果對象以及創建結果對象時所做的所有更改。

import { produceWithPatches } from 'immer'

const baseState = {
  todo: [{ text: 'Learn typescript!' }],
  done: false
}

const [nextState, patches, inversePatches] = produceWithPatches(baseState, draft => {
  draft.done = true;
  draft.todo.push({ text: 'Tweet about it' })
})

4. applyPatches函數

applyPatches函數將補丁應用於給定狀態的工具函數。

import { applyPatches } from 'immer'

const baseState = {
  todo: [{ text: 'Learn typescript!' }],
  done: false
}

const [nextState, patches] = produceWithPatches(baseState, draft => {
  draft.done = true;
  draft.todo.push({ text: 'Tweet about it' })
})

console.log(nextState) 
// {
//   todo: [
//     { text: 'Learn typescript!' },
//     { text: 'Tweet about it' }
//   ],
//   done: true
// }

const finalState = applyPatches(baseState, patches)

console.log(finalState)
// {
//   todo: [
//     { text: 'Learn typescript!' },
//     { text: 'Tweet about it' }
//   ],
//   done: true
// }

四、immer的應用場景

immer可以在數據和狀態管理中發揮作用。例如,在Redux中使用immer,您可以編寫簡潔,易於理解的代碼來處理應用程序狀態。此外,在使用可變狀態對象的情況下,immer使得單元測試更容易編寫和執行。

五、immer的總結

immer提供了一種輕鬆構建不可變對象的方法,它還提供了用於跟蹤變化的良好API。在實際開發中,immer幫助開發者在數據處理上更充分地利用了JavaScript的功能,使得代碼更加簡潔易讀。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/300441.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-29 12:51
下一篇 2024-12-29 12:51

相關推薦

  • Python棧操作用法介紹

    如果你是一位Python開發工程師,那麼你必須掌握Python中的棧操作。在Python中,棧是一個容器,提供後進先出(LIFO)的原則。這篇文章將通過多個方面詳細地闡述Pytho…

    編程 2025-04-29
  • Python操作數組

    本文將從多個方面詳細介紹如何使用Python操作5個數組成的列表。 一、數組的定義 數組是一種用於存儲相同類型數據的數據結構。Python中的數組是通過列表來實現的,列表中可以存放…

    編程 2025-04-29
  • lsw2u1:全能編程開發工程師的利器

    lsw2u1是一款多功能工具,可以為全能編程開發工程師提供便利的支持。本文將從多個方面對lsw2u1做詳細闡述,並給出對應代碼示例。 一、快速存取代碼段 在日常開發中,我們總會使用…

    編程 2025-04-29
  • Python刷課:優化學習體驗的利器

    Python刷課作為一種利用自動化技術優化學習體驗的工具已經被廣泛應用。它可以幫助用戶自動登錄、自動答題等,讓用戶在學習過程中可以更加專註於知識本身,提高效率,增加學習樂趣。 一、…

    編程 2025-04-29
  • Python操作MySQL

    本文將從以下幾個方面對Python操作MySQL進行詳細闡述: 一、連接MySQL資料庫 在使用Python操作MySQL之前,我們需要先連接MySQL資料庫。在Python中,我…

    編程 2025-04-29
  • Python代碼實現迴文數最少操作次數

    本文將介紹如何使用Python解決一道經典的迴文數問題:給定一個數n,按照一定規則對它進行若干次操作,使得n成為迴文數,求最少的操作次數。 一、問題分析 首先,我們需要了解迴文數的…

    編程 2025-04-29
  • Python磁碟操作全方位解析

    本篇文章將從多個方面對Python磁碟操作進行詳細闡述,包括文件讀寫、文件夾創建、刪除、文件搜索與遍歷、文件重命名、移動、複製、文件許可權修改等常用操作。 一、文件讀寫操作 文件讀寫…

    編程 2025-04-29
  • 面向對象編程、類和對象

    面向對象編程(Object-Oriented Programming, OOP)是一種編程方法,它將現實世界中的事物抽象為對象(Object),對象的屬性和方法被封裝成類(Clas…

    編程 2025-04-29
  • Python元祖操作用法介紹

    本文將從多個方面對Python元祖的操作進行詳細闡述。包括:元祖定義及初始化、元祖遍歷、元祖切片、元祖合併及比較、元祖解包等內容。 一、元祖定義及初始化 元祖在Python中屬於序…

    編程 2025-04-29
  • Python列表的讀寫操作

    本文將針對Python列表的讀取與寫入操作進行詳細的闡述,包括列表的基本操作、列表的增刪改查、列表切片、列表排序、列表反轉、列表拼接、列表複製等操作。 一、列表的基本操作 列表是P…

    編程 2025-04-29

發表回復

登錄後才能評論