我的编程空间,编程开发者的网络收藏夹
学习永远不晚

React状态的不变性实例详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

React状态的不变性实例详解

正文

不变性对应的英文单词是 Immutability,它不是 React 中的概念,但它对写一个正确的 React 程序至关重要。不考虑生命周期函数 shouldComponentUpdate 对组件重新渲染造成的影响,当组件的 state 发生变化时,组件将被重新渲染。

你可曾遇到过这样一种情况——你自认为改变了 state 的值,但是组件没有重新渲染?本文将揭露其中的缘由并介绍怎么编写符合 Immutability 原则的代码。

什么是 immutable

immutable 指不发生变化,这意味着创建新的值去替换原来的值,而非改变原来的值,与 immutable 相反的概念是 mutable,下面用代码演示 mutable 和 immutable。

let user = {name: 'Bela'}
user.name = 'CI' // 改变user的name属性
user.age = 12 // 给user新增age属性
user = {name: 'Bela'} // 用新的值替换原来的值

上述代码第 2 行和第 3 行都属于改变原来的值,只有第四行是新建一个对象,用新对象替换原来的对象。下面调用函数进一步说明 immutable 与 mutable。


function addAgeMutable(user: User) {
    user.age = 12 // 修改原来的
    return user
}
function addAgeImmutable(user: User) {
    const other = Object.assign({}, user) // 创建新的
    other.age = 12
    return other
}
let user1Original = {name: 'Bella'}
let user1New = addAgeMutable(user1Original) // 用 mutable 的方式
let user2Original = {name: 'Bella'}
let user2New = addAgeImmutable(user2Original) // 用 immutable 的方式
console.log('user1Original 与 user1New 相同吗?',user1Original === user1New) // true
console.log('user2Original 与 user2New 相同吗?',user2Original === user2New) // false

上述 addAgeMutable 函数直接在入参上新增 age 属性,但 addAgeImmutable 函数没有改变入参,而是新建了一个对象,在新对象上添加age属性。

总结一下,immutable 是指不修改原来的;mutable 是指在原来的基础上修改。通过 mutable 的方式修改变量会导致修改前后变量的引用不变。某些操作数组的方法会让原来的数组发生变化,比如:push/pop/shift/unshift/splice,这些方法是 mutable 的,而有一些操作数组的方法不会让原来的数组发生变化,而是返回一个新组件,比如:slice/concat,这些函数是 immutable 的。字符串、布尔值和数值操作都不改变原来的值,而是创建一个新的值。

React 与 Immutability

在 React 程序中,组件的 state 必须具备不变性,接下来演示修改state的正确与不正确的方式。为了说明state的组成结构,先定义个State接口,代码如下:

interface State {
  user: User
  hobbies: string[]
  time: string
}

从上述接口可以看出,组件有三个状态,分别为:user、hobbies 和 time,它们的数据类型各不相同。

修改 state 的错误案例

下面罗列的案例试图用 mutable 的方式修改 state,这些做法全部是错误的。

// 案例一
this.state.user.age = 13
// 案例二
this.setState({
    user: Object.assign(this.state.user, {age: 13})
})
// 案例三
this.setState({
    hobbies: this.state.hobbies.reverse(),
})
// 案例四
this.state.hobbies.length = 0
this.setState({
    hobbies: this.state.hobbies,
})
  • 案例一: 直接修改 user 的内部结构,修改前后 user 的引用不变。
  • 案例二: 错误使用 Object.assign,Object.assign 将第二个参数的属性合并到第一个参数上,然后将第一个参数返回,这意味着案例二还是修改了user的内部结构,修改前后user的引用不变。
  • 案例三: 使用reverse将数组翻转,它翻转的是原数组,翻转前后数据的引用不变。
  • 案例四: 修改hobbies的长度,修改前后hobbies的引用一样。

上述四个案例都不符合数据一旦创建就不发生变化的原则,由于调用了 setState 方法,所以对于用 React.Component 创建的组件而言,不会发生故障,对于用 React.PureComponent 创建的组件,会引发故障,即:界面不更新。

修改 state 的正确案例

下面罗列的案例与错误案例一一对应,它们通过 immutable 的方式修改 state。

    // 案例一
    this.setState({
        user: {...this.state.user, age: 13}
    })
    // 案例二
    this.setState({
        user: Object.assign({},this.state.user, {age: 13})
    })
    // 案例三
    this.setState({
        hobbies: [...this.state.hobbies].reverse()
    })
    // 案例四
    this.setState({
        hobbies: []
    })

上述案例都是新建一个值,用新的值替换原来的值,符合数据一旦创建就不发生变化的原则。

总结

在 react 应用中,更新 state 必须满足 Immutability 原则,因为 React.memo、PureComponent shouldComponentUpdate 和 React Hooks 通过浅比较确定 state 是否发生变更,如果变更 state 的方式不满足 Immutability 原则,它们会认为 state 的值没有变化。

在更新 state 并重新渲染时,React 会将类组件的 this.setState 与函数组件的 useState、useReducer hooks 区别对待。在函数组件中,React 要求所有 hooks 更新状态必须返回一个新的引用作为状态值,如果 React 发现状态更新来自 hook,它会检查该值的引用是否与以前的引用相同,如果相同,它将退出该函数组件的渲染流程,最终用户界面不更新。使用 this.setState 更新类的 state,React 并不关心状态的引用是否变化,只要在类组件中调用 this.setState,该组件一定会重新渲染。

以上就是React 状态的不变性实例详解的详细内容,更多关于React 状态不变性的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

React状态的不变性实例详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

React状态的不变性实例详解

这篇文章主要为大家介绍了React状态的不变性实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-16

Android 使用selector改变按钮状态实例详解

Android 使用selector改变按钮状态实例详解 在res/drawable文件夹新增一个文件,此文件设置了图片的触发状态,你可以设置 : state_pressed,state_checked,state_pressed,stat
2022-06-06

Mobx实现React 应用的状态管理详解

这篇文章主要为大家介绍了Mobx 实现 React 应用的状态管理,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-12-08

React竞态条件RaceCondition实例详解

这篇文章主要为大家介绍了React竞态条件RaceCondition实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-13

react组件实例属性props实例详解

这篇文章主要介绍了react组件实例属性props,本文结合实例代码给大家简单介绍了props使用方法,代码简单易懂,需要的朋友可以参考下
2023-01-30

Android 判断网络状态实例详解

Android 判断网络状态实例详解 实例代码package com.example.android; import java.io.IOException; import java.net.HttpURLConnection; im
2022-06-06

React竞态条件Race Condition实例详解

竞态条件(Race Condition)是指当多个线程同时访问共享资源时,最终的结果与线程的执行顺序有关,从而导致程序出现不正确的行为。下面是一个React中的竞态条件实例:假设有一个计数器组件 Counter,它包含一个按钮和一个显示计数
2023-08-15

react组件实例属性state详解

这篇文章主要介绍了react组件实例属性state,有状态state的组件称作复杂组件,没有状态的组件称为简单组件,状态里存储数据,数据的改变驱动页面的展示,本文结合实例代码给大家详细讲解,需要的朋友可以参考下
2023-02-02

react实现组件状态缓存的示例代码

本文主要介绍了react实现组件状态缓存的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-02-24

Android 动态改变布局实例详解

Android 动态改变布局 最近项目需求,动态的改变布局,为了增加客户体验,尤其是在输入框出现小键盘的时候,为了避免小键盘遮挡APP内容就需要动态改变布局: 先看下实现效果图:
2022-06-06

编程热搜

目录