重构利器:如何用 Immer 优雅地管理应用状态

2024-02-11 15:44

本文主要是介绍重构利器:如何用 Immer 优雅地管理应用状态,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. immer

immer 是一个 JavaScript 库,用于处理不可变数据的状态更新。不可变数据意味着一旦创建,数据结构就不能被修改。在编写复杂的应用程序时,不可变性可以带来一系列好处,比如更容易追踪数据的改变、更容易实现撤销/重做功能以及更简单的状态管理。

然而,处理不可变数据结构通常需要编写大量的样板代码,尤其是在更新嵌套结构时。immer 库通过提供一个简单的可变(mutable)API 来更新不可变(immutable)状态,从而简化了这一过程。

immer 的核心概念是“草稿状态”(draft state)。这个库允许你编写看似可变的代码来更新一个不变的状态,但实际上,你是在修改的一个临时的草稿状态。一旦修改完成,immer 会基于这个草稿状态产生一个新的不可变状态。

2. 诞生背景

immer 的诞生背景主要与在 JavaScript 应用中管理复杂的不可变状态有关。在 React 和 Redux 等现代前端框架和库中,不可变数据的概念非常重要,因为它帮助开发者避免直接修改状态,从而避免潜在的副作用和性能问题。不可变数据还使得状态的变化更加可预测,便于跟踪和调试,同时也简化了复杂的功能如时间旅行(time travel debugging)和状态快照的实现。

React 的 setState 方法和 Redux 的 reducer 函数都要求你返回一个新的状态对象,而不是修改原有的状态。当状态结构简单时,这通常不是问题,但当应用逐渐变得复杂,状态结构也变得更加嵌套时,更新状态会变得越来越繁琐。例如,如果你需要更新一个嵌套的数组或对象,你需要逐层克隆所有父级对象,直到达到你想要修改的属性。这不仅编写起来复杂,而且容易出错。

为了解决这个问题,Michel Weststrate(也是 MobX 库的作者)创建了 immer。他的目标是创建一个库,它能够让你以一种更自然和声明式的方式更新不可变状态,同时避免手动处理复杂的对象和数组克隆操作。通过 immer,你可以继续编写简单直观的可变代码,但是产生的结果是按照不变性原则处理的,这样就既保持了代码的简洁,也确保了状态的不可变性。

简而言之,immer 的诞生背景是为了解决在处理复杂不可变状态时的编码复杂性问题,同时帮助开发者避免常见的不可变数据操作错误,提高代码的可维护性和可读性。

3. immer 对象克隆算法的简单实现

immer 库使用了一种称为结构共享的技术来实现对象克隆,这种技术可以有效地创建新的不可变状态,同时尽可能地重用旧状态中未修改的部分。下面是一个简化版的 immer 克隆算法的实现,用于展示其基本原理:

function createDraft(initialState) {// 遍历对象,递归地将其属性转化为可写。function createProxy(state) {if (typeof state === "object" && state !== null) {return new Proxy(state, {get(target, prop) {if (prop === "isDraft") return true;return createProxy(target[prop]);},set(target, prop, value) {target[prop] = value;return true;},});}return state;}return createProxy(initialState);
}function finishDraft(draft) {// 遍历对象的草稿版本,并递归地生成最终的不可变状态。function finalize(state) {

这篇关于重构利器:如何用 Immer 优雅地管理应用状态的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/700183

相关文章

Java逻辑运算符之&&、|| 与&、 |的区别及应用

《Java逻辑运算符之&&、||与&、|的区别及应用》:本文主要介绍Java逻辑运算符之&&、||与&、|的区别及应用的相关资料,分别是&&、||与&、|,并探讨了它们在不同应用场景中... 目录前言一、基本概念与运算符介绍二、短路与与非短路与:&& 与 & 的区别1. &&:短路与(AND)2. &:非短

Redis实现RBAC权限管理

《Redis实现RBAC权限管理》本文主要介绍了Redis实现RBAC权限管理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1. 什么是 RBAC?2. 为什么使用 Redis 实现 RBAC?3. 设计 RBAC 数据结构

Flutter监听当前页面可见与隐藏状态的代码详解

《Flutter监听当前页面可见与隐藏状态的代码详解》文章介绍了如何在Flutter中使用路由观察者来监听应用进入前台或后台状态以及页面的显示和隐藏,并通过代码示例讲解的非常详细,需要的朋友可以参考下... flutter 可以监听 app 进入前台还是后台状态,也可以监听当http://www.cppcn

Spring AI集成DeepSeek三步搞定Java智能应用的详细过程

《SpringAI集成DeepSeek三步搞定Java智能应用的详细过程》本文介绍了如何使用SpringAI集成DeepSeek,一个国内顶尖的多模态大模型,SpringAI提供了一套统一的接口,简... 目录DeepSeek 介绍Spring AI 是什么?Spring AI 的主要功能包括1、环境准备2

Spring AI与DeepSeek实战一之快速打造智能对话应用

《SpringAI与DeepSeek实战一之快速打造智能对话应用》本文详细介绍了如何通过SpringAI框架集成DeepSeek大模型,实现普通对话和流式对话功能,步骤包括申请API-KEY、项目搭... 目录一、概述二、申请DeepSeek的API-KEY三、项目搭建3.1. 开发环境要求3.2. mav

mac安装nvm(node.js)多版本管理实践步骤

《mac安装nvm(node.js)多版本管理实践步骤》:本文主要介绍mac安装nvm(node.js)多版本管理的相关资料,NVM是一个用于管理多个Node.js版本的命令行工具,它允许开发者在... 目录NVM功能简介MAC安装实践一、下载nvm二、安装nvm三、安装node.js总结NVM功能简介N

MobaXterm远程登录工具功能与应用小结

《MobaXterm远程登录工具功能与应用小结》MobaXterm是一款功能强大的远程终端软件,主要支持SSH登录,拥有多种远程协议,实现跨平台访问,它包括多会话管理、本地命令行执行、图形化界面集成和... 目录1. 远程终端软件概述1.1 远程终端软件的定义与用途1.2 远程终端软件的关键特性2. 支持的

MySQL 中的服务器配置和状态详解(MySQL Server Configuration and Status)

《MySQL中的服务器配置和状态详解(MySQLServerConfigurationandStatus)》MySQL服务器配置和状态设置包括服务器选项、系统变量和状态变量三个方面,可以通过... 目录mysql 之服务器配置和状态1 MySQL 架构和性能优化1.1 服务器配置和状态1.1.1 服务器选项

SpringBoot中使用 ThreadLocal 进行多线程上下文管理及注意事项小结

《SpringBoot中使用ThreadLocal进行多线程上下文管理及注意事项小结》本文详细介绍了ThreadLocal的原理、使用场景和示例代码,并在SpringBoot中使用ThreadLo... 目录前言技术积累1.什么是 ThreadLocal2. ThreadLocal 的原理2.1 线程隔离2

linux进程D状态的解决思路分享

《linux进程D状态的解决思路分享》在Linux系统中,进程在内核模式下等待I/O完成时会进入不间断睡眠状态(D状态),这种状态下,进程无法通过普通方式被杀死,本文通过实验模拟了这种状态,并分析了如... 目录1. 问题描述2. 问题分析3. 实验模拟3.1 使用losetup创建一个卷作为pv的磁盘3.