主要困惑的内容在两个 onClick 事件里,一个对于 state 是 immutable 的,另一个不是,但是效果是相同的。疑惑的点在于
import { useState } from "react"
function App() {
let [personList, setPersonList] = useState([{ name: "jack", age: 18 }])
const onClick1 = () => {
let newState = [...personList]
newState.push({ name: "kk", age: 1 })
// 这里相当于直接修改了 personList[0].name 上的值,对于 personList 这个 state 没有做到 immutable
newState[0].name = "ddddddd"
setPersonList(newState)
}
const onClick2 = () => {
setPersonList([
{
// 这里先复制一遍 personList[0],再复制,personList 这个 state 在过程中是只读的,是 immutable
...personList[0],
name: "ddddddd",
},
...personList.slice(1),
{ name: "kk", age: 1 },
])
}
return (
<div className="App">
<button onClick={onClick1}>add1</button>
<button onClick={onClick2}>add2</button>
{personList.map((item, index) => {
return <div key={index}>{item.name}</div>
})}
</div>
)
}
export default App
补充一下上述语境中 immutable 的定义,以常见的 immutable 库 immer 为例,可以看到执行函数,返回 new1 后,old 的值是不变的,这样可以认为 old 是 immutable 的
import { produce } from "immer"
const old = [{ name: "jack", age: 18 }]
const new1 = produce(old, (state) => {
state[0].name = "ddddddd"
state.push({ name: "kk", age: 1 })
})
console.log("原始值", old) // 原始值 [ { name: 'jack', age: 18 } ]
console.log("新值", new1) // 新值 [ { name: 'ddddddd', age: 18 }, { name: 'kk', age: 1 } ]
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.