我想当然地认为只要dataSource改变,那么<Table>
组件就会重新渲染,
但是有一种特殊情况例外:
在onFilter()
中不写筛选条件,在调用filterDropdown
进行列筛选的时候,通过handleSearch
改变/保存dataSource
的状态,此时<Table>
重新渲染,但是拿的不是dataSource={xxx}
,而是拿的filterDropdown
中的onFilter()
中的dataSource
,而onFilter
中是没有写代码的,所以返回暂无数据
。
PS:
解释下我不在onFilter()
中写代码的原因,因为我已将dataSource保存到state中,所以需要setState
去更改dataSource
数据,但是onFilter()
方法是在componentDidUpdate()
周期调用的,所以setState
会报错,所以我想到了在onClick中setState,但这样console.log出来,dataSource更改了,但是table显示暂无数据。
示例代码:
handleSearch=()=>{
this.setState({dataSource:dataSourceB})
}
getColumnSearchProps = (dataIndex) => ({
filterDropdown: ({
setSelectedKeys, selectedKeys, confirm, clearFilters,
}) => (
<div>
<Input
value={selectedKeys[0]}
onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
onPressEnter={() => this.handleSearch(selectedKeys, confirm)}
/>
<Button
onClick={() => this.handleSearch(selectedKeys, confirm)}
>
Search
</Button>
</div>
),
//筛选条件,没有写代码,所以没有数据返回,所以是暂无数据
onFilter: (value, record) =>{ },
})
render{
return(
<Table
column={ [{...this.getColumnSearchProps('name')}}
dataSource={dataSourceA}
>
)
}
复制代码
示例代码地址:
ant.design/components/…
列筛选逻辑的流程图如下:
onFilter()的源码:
getLocalData(state?: TableState<T> | null, filter: boolean = true): Array<T> {
const currentState: TableState<T> = state || this.state;
const { dataSource } = this.props;
let data = dataSource || [];
// 优化本地排序
//就是这行代码,通过slice,另开内存来保存dataSource
data = data.slice(0);
const sorterFn = this.getSorterFn(currentState);
if (sorterFn) {
data = this.recursiveSort(data, sorterFn);
}
// 筛选
if (filter && currentState.filters) {
Object.keys(currentState.filters).forEach(columnKey => {
const col = this.findColumn(columnKey) as any;
if (!col) {
return;
}
const values = currentState.filters[columnKey] || [];
if (values.length === 0) {
return;
}
const onFilter = col.onFilter;
data = onFilter
? data.filter(record => {
return values.some(v => onFilter(v, record));
})
: data;
});
}
return data;
}
复制代码
onFilter()的源码地址:
github.com/ant-design/…
(完)