1.9 KiB
1.9 KiB
title, impact, impactDescription, tags
| title | impact | impactDescription | tags |
|---|---|---|---|
| 使用 toSorted() 替代 sort() 以实现不可变性 | MEDIUM-HIGH | 防止 React 状态中的突变(mutation)错误 | javascript, arrays, immutability, react, state, mutation |
使用 toSorted() 替代 sort() 以实现不可变性
.sort() 会原地(in place)修改数组,这可能导致 React 状态和属性(props)出现错误。请使用 .toSorted() 创建一个新的已排序数组,避免修改原数组。
错误写法(修改了原数组):
function UserList({ users }: { users: User[] }) {
// 修改了 users 属性数组!
const sorted = useMemo(
() => users.sort((a, b) => a.name.localeCompare(b.name)),
[users]
)
return <div>{sorted.map(renderUser)}</div>
}
正确写法(创建新数组):
function UserList({ users }: { users: User[] }) {
// 创建新的已排序数组,原数组不变
const sorted = useMemo(
() => users.toSorted((a, b) => a.name.localeCompare(b.name)),
[users]
)
return <div>{sorted.map(renderUser)}</div>
}
为什么这在 React 中很重要:
- 对属性(props)/状态的修改会破坏 React 的不可变性模型——React 期望属性和状态被视为只读
- 会导致闭包过时(stale closure)错误——在闭包(回调函数、副作用)内修改数组可能引发意外行为
浏览器支持(旧浏览器降级方案):
.toSorted() 在所有现代浏览器中可用(Chrome 110+、Safari 16+、Firefox 115+、Node.js 20+)。对于较旧的环境,请使用展开运算符:
// 旧浏览器降级方案
const sorted = [...items].sort((a, b) => a.value - b.value)
其他不可变数组方法:
.toSorted()—— 不可变排序.toReversed()—— 不可变反转.toSpliced()—— 不可变拼接.with()—— 不可变元素替换