更新对象
当你想更新一个对象和数组时,你需要创建一个新的对象(或复制现有的对象),然后用这个副本来更新状态
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 分离。
数据变化监听原理:
- 状态(State)更新 :当组件的状态通过
setState
进行更新时,React 会比较新旧状态,然后在合适的时机(在异步批量更新中)触发重新渲染。 - 属性(Props)更新:当组件的属性发生变化时,React 会触发更新并重新渲染组件。
- 上下文(Context)变化:当上下文中的值发生变化时,依赖于该上下文的组件会重新渲染。
Vue为什么不需要创建新的数组
Vue有一个响应式系统,会追踪属性的变化,必要时触发视图更新。Vue2的响应式系统对于数组的变化使用了重写数组的特定方法,比如数组push方法,Vue 会通知相关的依赖(比如模板中渲染这个数组的部分)需要进行更新,触发视图的重新渲染,以展示最新的数组内容。
在Vue3中,采用了更高效的基于 Proxy 的响应式系统。它可以更精准地捕获数组的变化,包括索引的直接赋值等操作。因此,在Vue3中,你可以直接修改数组的元素,而不必依赖特定的数组方法,Vue 3 的响应式系统会更好地追踪这些变化并触发相应的更新。