首页 >web前端 >js教程 >比较 React Mutative 与 React Immer

比较 React Mutative 与 React Immer

PHPz
PHPz原创
2024-08-25 06:31:32613浏览

Comparing React Mutative vs. React Immer

管理 React 应用程序中的状态是创建动态和响应式用户界面的重要组成部分。传统上,开发人员依赖于不可变的更新,这会生成经过必要修改的状态的新副本。虽然此方法提供了可预测性并有助于调试,但它可能会带来性能损失,特别是在处理大型或复杂的数据结构时。

本文介绍了两种流行的用于处理状态的 React 框架;反应突变和沉浸。尽管通过不同的方式,这两个库都促进了不变性。

React Mutative 概述

Mutative 的实现与 Immer 非常相似,尽管更强大。 Mutative 比 Immer 和原生减速器更有效地处理数据。 根据 Mutative 团队的说法,这种状态管理解决方案使不可变更新变得更加容易。它比普通手工制作的减速机大约快两到六倍,比 Immer 快 10 倍以上。
以下是 Mutative.js 的一些好处:

  • 简洁:代码变得更易读、更容易编写。
  • 性能:这比手动不可变更新更快,特别是对于大型数据结构。
  • 减少错误:有助于避免状态对象的意外突变。

例如,假设有一个包含列表的状态对象。我们打算将列表中的最后一项标记为已完成,然后添加新项目:

const state = {
  list: [
    { text: 'Learn JavaScript', done: true },
    { text: 'Learn React', done: true },
    { text: 'Learn Redux', done: false },
  ],
};

如果我们要使用常规的不可变数据更新,我们可以编写如下:

const nextState = {
  ...state,
  list: [
    ...state.list.slice(0, 2),
    {
      ...state.list[2],
      done: true,
    },
    { text: 'Learn Mutative', done: true },
  ],
};

但是在使用 Mutative 时,我们可以这样写:

import { create } from 'mutative';

const nextState = create(state, (draft) => {
  draft.list[2].done = true;
  draft.list.push({ text: 'Learn Mutative', done: true });
});

这就是Mutative的基本用途,它可以让我们更轻松地实现不可变的更新。

React Immer 概述

Immer,在德语中的意思是“总是”,是一个小包,可以让使用不可变状态变得更加方便。荣获 2019 年 JavaScript 开源奖“最具影响力贡献”奖。

React Immer 的优点

这些好处往往是通过确保您始终创建对象、数组或映射的编辑副本而不是更改其任何属性来实现的。这会使编写代码变得非常困难,并且很容易无意中打破此类限制。通过解决这些问题,Immer 将帮助您坚持不可变数据方法。以下是 React Immer 的一些好处:

  • 如果 Immer 检测到无意的突变,它会报告错误。

  • Immer 消除了对不可变对象进行深度修改时所需的常规样板代码的要求。如果没有 Immer,则必须在各个级别手动复制对象。通常,通过进行大量...传播操作。使用 Immer 时,会对草稿对象进行修改,草稿对象会记录这些修改并创建适当的副本,而不更改原始对象。

  • Immer 并不要求您掌握某些 API 或数据结构即可从该范式中获利。 Immer 允许您访问纯 JavaScript 数据结构以及众所周知的可变 JavaScript API,同时保持安全。

    代码示例

    下面是一个用于快速比较的简单示例:

const baseState = [
    {
        title: "Learn JavaScript",
        done: true
    },
    {
        title: "Try Immer",
        done: false
    }
]

假设我们有之前的基本状态,我们需要更新第二个待办事项并添加第三个待办事项。然而,我们不想改变原来的baseState并避免深度克隆(以维持第一个待办事项)。

不带浸入器

如果没有 Immer,保持不变性需要我们复制状态对象的每个受影响的级别。

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"})

与沉浸式

Immer 简化了这个过程。我们可以使用生成函数,该函数将我们希望开始的状态作为其第一个参数,将一个称为配方的函数作为其第二个参数,该函数将收到一个草稿,我们可以对其进行简单的修改。一旦配方完成,突变就会被记录并用于创建下一个状态。 generate 将处理所有必要的复制,同时还通过冻结数据来保护数据免受未来无意的更改。

import {produce} from "immer"

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

您正在寻找带有 React 的 Immer 吗?欢迎您直接访问React + Immer网站。

核心功能

Mutative 和 Immer 都以概念上相似的方式实现了不可变更新,但存在影响性能的关键实现差异。详细介绍如下:

  1. Draft State: Both libraries create a draft version of the original state object. This draft behaves mostly like the original state, allowing you to write updates as if you were mutating it directly.
  2. Immutability Behind the Scenes: When you make changes to the draft state, these libraries aren't modifying the original object. Instead, they track the changes you make.
  3. Generating a New State: Once you're done with your updates in the draft state, Mutative, and Immer use different approaches to create a new, immutable state object reflecting the changes:
  4. Mutative: It leverages a high-performance algorithm to efficiently create a new data structure with the modifications from the draft. This approach prioritizes speed.
  5. Immer: It employs a proxy object that intercepts mutations on the draft and uses that information to construct a completely new, immutable state object. This approach offers more flexibility but can have some performance overhead. ## Performance Comparison When it comes to raw performance, Mutative reigns supreme over Immer, especially for updates involving large data structures. Here's why:
  6. Speed Demon: Benchmarks show Mutative can be a staggering 2-6 times faster than writing state updates with traditional reducers and a whopping over 10 times faster than Immer in its default settings.
  • Secret Sauce: This speed advantage boils down to how each library creates the final immutable state object. Mutative employs a highly optimized algorithm that efficiently builds a new data structure reflecting the changes you made in the draft, prioritizing raw speed.

  • Immer's Overhead: Immer, on the other hand, utilizes a proxy object to track mutations on the draft state. This approach offers more flexibility but comes with an overhead that can significantly slow things down, particularly when dealing with large datasets. It's like adding an extra step in the process.

  • Auto-Freeze and the Tradeoff: Immer offers an optional feature called auto-freeze, which helps prevent accidental modifications to the original state. This is great for safety, but it comes at a performance cost. Disabling auto-freeze can bring Immer closer to Mutative's speed, but then you lose the safety net.

    The Ease of Use Comparison

    Both Mutative and Immer offer an intuitive way to write state updates that appear to mutate the state but ultimately result in immutable updates. However, there are some differences in syntax and potential for errors:
    Syntax Mutative: Leverages familiar syntax that resembles traditional mutations. You write code as if you're directly modifying the state object.
    Example:

const draft = createDraft(currentState);
draft.todos.push({ text: 'Buy milk' });
const newState = commit(draft);

Immer Syntax: Requires using specific Immer functions like produce to wrap your update logic.
Example:

const newState = produce(currentState, draft => {
  draft.todos.push({ text: 'Buy milk' });
});

Draft Escapes

Draft escapes occur when you unintentionally modify the original state object instead of the draft copy in libraries like Mutative and Immer.
Mutative: While Mutative's syntax might feel familiar, there's a higher risk of accidentally modifying the original state object (draft escapes). This can happen if you forget to use the commit function to finalize the changes and create the new state. It requires stricter discipline to ensure all modifications go through the draft.
Immer: Immer's syntax explicitly forces you to work within the draft state using functions like produce. This reduces the chance of accidentally modifying the original state, making it inherently safer.

Conclusion

Ultimately, the best choice depends on your specific project requirements and team preferences. Consider trying both libraries on a small project to see which one feels more comfortable for your developers.

以上是比较 React Mutative 与 React Immer的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn