React中使用useState实现表格排序时布尔值无法正常更新是什么原因
问题原因
核心问题是你将排序方向标识asc定义为了组件内部的普通局部变量,没有通过useState存储:
- React组件在每次state更新触发重渲染时,所有局部普通变量都会被重新初始化,你对
asc的修改会在重渲染后直接丢失 - 第一次点击触发排序后,你调用
SetArray更新了列表state,触发组件重渲染,此时代码中的let asc = true会重新执行,asc直接被重置为初始值true - 后续再点击时,永远只会走升序排序的分支,但此时列表已经是升序状态,排序后结果和当前列表完全一致,看起来就像排序不再生效
修复方案
- 将
asc也改为用useState保存的响应式状态,修改时用对应的setter方法更新,保证状态在重渲染后不会丢失 - 优化字符串排序的比较逻辑,用
localeCompare替代直接大小比较,适配多语言场景 - 修复代码中HTML结构错误(最外层
Tablediv提前闭合的问题) - 建议变量、普通函数使用小驼峰命名,避免和组件命名规范冲突
修复后的完整代码如下:
import React from 'react' import { useState } from 'react' export const Table = () => { // 排序方向改为state存储 const [asc, setAsc] = useState(true) const [array2, setArray] = useState([ {rank:1,name:'Sam', age:25, gender:true}, {rank:2,name:'Bill', age:35, gender:true}, {rank:3,name:'John', age:22, gender:true}, {rank:4,name:'Sarah', age:19, gender:false} ]) const alpha2 = () => { let newArr if (asc) { // 用localeCompare做字符串排序更规范 newArr = [...array2].sort((a,b) => a.name.localeCompare(b.name)) setAsc(false) } else { newArr = [...array2].sort((a,b) => b.name.localeCompare(a.name)) setAsc(true) } setArray(newArr) } // 原代码中引用的年龄排序方法可自行补充实现 const Numa = () => { // 年龄排序逻辑 } return ( <div className="Table"> <h3>Table 2</h3> <div className="Standings"> <div className="column"> <div> <h3>Rank</h3></div> <div onClick={()=>alpha2()}> <h3>Name</h3></div> <div> <h3 onClick={()=>Numa()}>Age</h3></div> <div> <h3>Gender</h3></div> </div> {array2.map((profile)=>( <div key={profile.rank} className="column"> <div> <h3>{profile.rank}</h3></div> <div> <h3>{profile.name}</h3></div> <div> <h3>{profile.age}</h3></div> <div> <h3>{profile.gender?'male': 'female'}</h3></div> </div> ))} </div> </div> ) } export default Table
内容的提问来源于stack exchange,提问作者Maxwell Derry
相关产品推荐
相关产品推荐

