React为什么要这样更新数组和对象

更新对象

当你想更新一个对象和数组时,你需要创建一个新的对象(或复制现有的对象),然后用这个副本来更新状态

js 复制代码
import { useState } from 'react'

export default function App() {
    const [person, setPerson] = useState({
        name: '我是柯南',
        artwork: {
          title: '侦探',
          age: 8
        }
    });
    function changeName() {
        setPerson({
          ...person,
          name: '我是新一'
        });
    }
    return (
        <div>
            <div onClick={changeName}>点我修改名字</div>
            <div>{person.name}</div>
        </div>
    )
}

更新状态中的数组

和对象同理,需要创建一个新数组。

js 复制代码
import { useState } from 'react'

const initialList = [
  { id: 0, name: '新一'},
  { id: 1, name: '柯南'},
];

export default function App() {
    const [person, setPerson] = useState(initialList);
    function changeName() {
        setPerson(person.map(item => {
            if (item.id === 0) {
                return { ...item, name: '我不是新一' };
            } else {
                return item;
            }
        }));
    }
    function addName() {
        // 创建一个新数组,并将新元素添加到新数组中
        const newPserson = [...person, {id: person.length + 1, name: `小兰${ person.length + 1}`}]
        // 更新状态以触发重新渲染,并将新数组作为新的状态值
        setPerson(newPserson)
    }
    return (
        <div>
            <div onClick={changeName}>点我修改名字</div>
            <div onClick={addName}>点我加人</div>
            {person.length && person.map(item => <div key={item.id}>{item.name}</div>)}
        </div>
    )
}

React为什么要这样更新数组和对象

React是依赖于引用比较来检测状态变化。当你直接修改现有的数组或对象的内容,无法检测到数组和对象的变化,因为它仅仅是比较引用,如果引用相同,即使数组或对象发生了变化,React认为状态没有发生变化而不会重新去渲染组件。 React为了确保正确检测到状态变化并触发重新渲染,需要创建一个新的数组或对象或复制现有的数组,并对其进行修改,,这样React就能够检测到数组引用的变化,从而更新状态并重新渲染组件。

例如,数组使用 Array.prototype.concat()、展开操作符 ...Array.prototype.slice() 等方法来创建一个新数组,然后对新数组进行修改并更新状态,这样可以确保React能够正确地捕捉到状态的变化。

React18的状态更新

React18引入了一个新的特性,称为"Concurrent Mode"(并发模式),这项特性旨在提高 React 应用的性能和响应能力。在 Concurrent Mode 下,React 18 采用了新的更新机制和渲染优化。,通过异步批量更新、React Fiber架构、Reconciler 和 Renderer 分离。

数据变化监听原理:

  1. 状态(State)更新 :当组件的状态通过 setState 进行更新时,React 会比较新旧状态,然后在合适的时机(在异步批量更新中)触发重新渲染。
  2. 属性(Props)更新:当组件的属性发生变化时,React 会触发更新并重新渲染组件。
  3. 上下文(Context)变化:当上下文中的值发生变化时,依赖于该上下文的组件会重新渲染。

Vue为什么不需要创建新的数组

Vue有一个响应式系统,会追踪属性的变化,必要时触发视图更新。Vue2的响应式系统对于数组的变化使用了重写数组的特定方法,比如数组push方法,Vue 会通知相关的依赖(比如模板中渲染这个数组的部分)需要进行更新,触发视图的重新渲染,以展示最新的数组内容。
在Vue3中,采用了更高效的基于 Proxy 的响应式系统。它可以更精准地捕获数组的变化,包括索引的直接赋值等操作。因此,在Vue3中,你可以直接修改数组的元素,而不必依赖特定的数组方法,Vue 3 的响应式系统会更好地追踪这些变化并触发相应的更新。

相关推荐
风月说与山鬼6 小时前
三、大括号语法
前端·react.js
Zkaisen20 小时前
mtreoCVE-2025-11953学习(目录遍历与远程命令执行)
学习·react native·react.js·metro
zzzzzz31021 小时前
react-bits 为什么会吸引前端开发者:别把动效当装饰,先把它当成页面能力
前端·react.js·动效
风月说与山鬼1 天前
二、React入口文件(main.jsx)
前端·react.js
张元清2 天前
React useTimeout Hook:声明式 setTimeout 与自动清理 (2026)
javascript·react.js
嘟嘟07172 天前
JWT 登录认证完整流程(React + Vite 实战复习)
react.js·vite
meilindehuzi_a2 天前
React JWT 登录鉴权实战:从无状态 HTTP 到路由守卫、Zustand 与 Axios 拦截器
前端·react.js·http
张元清2 天前
React useEventListener Hook:类型安全的 DOM 事件监听 (2026)
javascript·react.js
l1m0_3 天前
React+Tailwind+AI 实战:连锁餐饮管理后台从零到一开发复盘
前端·react.js·ui·ai·ai设计
FungLeo3 天前
React 管理后台实战 · 多角色后台的菜单和路由怎么按角色收口?配置表驱动,新增权限不碰业务代码
前端·react.js·多角色菜单