React AntD表格存columns于state时筛选图标颜色不更新
表格筛选图标颜色不随筛选状态更新问题
问题表现
对Ant Design表格应用筛选规则时,需要同步切换筛选图标为彩色状态,但实际图标颜色始终无法正常更新。
问题复现代码
const Table = () => { // 原代码此处存在语法错误:useState括号位置错误 const [tableFilters, setTableFilters = useState({name: []}) let tableColumns = [ { title: 'Name', dataIndex: 'name', key: 'name', filters: [], filterDropdownVisible: false, filterIcon: (filtered: boolean) => { return ( // 原代码此处引用了未定义的filters变量 <TableFilterIcon filterColumnData={filters.name.data} /> ) }, }, ] const [columns, setColumns] = useState(tableColumns) return ( <> <CommonTable data={data} columns={tableColumns} /> </> ) } export default Table
实现逻辑为:在TableFilterIcon组件中根据当前选中的筛选条件判断渲染无颜色/彩色图标,存在生效筛选规则时展示彩色图标。但应用筛选后TableFilterIcon组件未触发重渲染,直接导致图标颜色无法更新。
补充现象:如果不将columns存储在state中,而是直接把columns配置传给CommonTable组件,该功能可以正常运行。
问题原因
- 核心原因:将columns存入state后,state里的columns配置是初始渲染时生成的快照,后续
tableFilters筛选状态更新时,state内的columns不会自动同步更新,filterIcon里引用的筛选值始终是初始值,无法触发组件重渲染。 - 代码本身存在语法错误:
useState的解构括号位置错误,filterIcon回调中引用了未定义的filters变量,也会导致逻辑异常。 - 直接在渲染函数中定义columns传入组件时,每次组件重渲染都会生成新的columns配置,能拿到最新的筛选状态,所以功能正常,但这种写法会带来额外的重渲染开销。
解决方案
方案1:使用Antd内置的筛选状态参数(最优解)
Antd Table的filterIcon回调默认会传入filtered布尔参数,代表当前列是否处于激活的筛选状态,不需要自己额外维护筛选状态传入,直接用这个参数控制图标样式即可,代码最简洁也最符合框架设计:
const Table = () => { const columns = [ { title: 'Name', dataIndex: 'name', key: 'name', filters: [], // 直接使用回调自带的filtered参数判断图标状态 filterIcon: (filtered) => <TableFilterIcon isActive={filtered} /> } ] return <CommonTable data={data} columns={columns} /> } export default Table
注意:如果
CommonTable是二次封装的组件,需要确保filterIcon的回调参数正常透传,不要被覆盖拦截。
方案2:自定义筛选逻辑时用useMemo缓存columns
如果需要根据自己维护的tableFilters状态判断图标样式,不要把columns存入state,直接用useMemo包裹columns配置,将依赖的筛选状态加入依赖数组,既可以保证状态更新时columns同步更新,也能避免不必要的重渲染:
import { useMemo, useState } from 'react' const Table = () => { // 修正原代码useState语法错误 const [tableFilters, setTableFilters] = useState({ name: [] }) const columns = useMemo(() => [ { title: 'Name', dataIndex: 'name', key: 'name', filters: [], filterIcon: () => <TableFilterIcon filterColumnData={tableFilters.name} /> } // 依赖的筛选状态变化时,自动重新生成columns ], [tableFilters]) return <CommonTable data={data} columns={columns} /> } export default Table
方案3:必须存columns到state时手动同步更新
如果业务场景强制要求将columns存入state管理,需要在筛选状态tableFilters更新时,同步调用setColumns更新列配置中filterIcon的传参,保证传入TableFilterIcon的props是最新值。这种写法维护成本较高,非必要不推荐。
内容的提问来源于stack exchange,提问作者lazyCoder
相关产品推荐
相关产品推荐

