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