React Hooks是React 16.8版本引入的新特性,它的作用是为函数组件提供了状态管理和副作用处理的能力。
在React之前,函数组件被限制在只能使用无状态的函数组件,无法使用状态和生命周期方法。Hooks的引入解决了这个限制,使得函数组件可以拥有和类组件相似的功能。
React Hooks的主要作用包括:
总体而言,React Hooks的作用是为函数组件提供了更多的功能和灵活性,使得函数组件能够更好地管理状态、处理副作用和访问上下文,从而简化了组件的开发和维护。它们使得函数组件成为了开发React应用的首选方式,并且在实际项目中得到了广泛的应用和验证。
在很多表格中,数据量是一次性直接返回的,如果增加一个搜索输入框+搜索按钮的话有点笨重,可以直接在表头位置增加搜索按钮
在表格所在组件中实现这个功能直接编写代码就行了,但是如果有多个表格需要使用到该功能,就需要将它提取出来
创建了一个名为searchInput的引用,用于获取搜索输入框的DOM元素。
然后,使用useState定义了两个状态变量:searchText和searchedColumn。
定义了handleSearch方法和handleReset方法。
定义了getColumnSearchProps方法,它接收三个参数:dataIndex、title和index2。这个方法返回一个包含多个属性和方法的对象,用于配置表格搜索功能。
返回一个包含搜索输入框和两个按钮的div元素。
包含搜索图标的Icon组件
根据搜索状态来决定图标的颜色,当进行搜索时,图标会变为蓝色
实现具体的搜索逻辑。
根据dataIndex和index2参数来判断记录中对应字段的值是否包含搜索关键词。
如果传入了index2,则比对那一列中的
record[dataIndex][index2]
不传入则是
record[dataIndex]
根据获取数据的层级来判断是否需要使用index2
使用index2的原因是,某些数据的层级较深,比如数据是「identity.uri」
{
title: '录制Identity',
dataIndex: 'identity.uri',
key: 'identity',
width: 200,
...getColumnSearchProps('identity', '录制Identity', 'uri'),
},
不使用index2的数据是:
{
title: '录制Identity',
dataIndex: 'originUri',
key: 'originUri',
width: 200,
...getColumnSearchProps('originUri', '录制Identity'),
},
当搜索框显示时自动选中搜索框
渲染表格中的每一行数据。
如果当前列是正在搜索的列,它会使用react-highlight-words组件对匹配的关键词进行高亮显示。
import useTableColumnSearch from '@/hooks/useTableColumnSearch';
const { getColumnSearchProps } = useTableColumnSearch();
// 表格的Columns
{
title: '录制Identity',
dataIndex: 'identity.uri',
key: 'identity',
width: 200,
...getColumnSearchProps('identity', '录制Identity', 'uri'),
},
使用该方式后可以:简化组件逻辑,方便复用
import React, { useRef, useState } from 'react';
import { Input, Button, Icon } from 'antd';
import Highlighter from 'react-highlight-words';
/*
* 表格搜索
* */
const useTableColumnSearch = () => {
const searchInput = useRef();
const [searchText, setSearchText] = useState('');
const [searchedColumn, setSearchedColumn] = useState('');
const handleSearch = (selectedKeys, confirm, dataIndex) => {
confirm();
setSearchText(selectedKeys[0]);
setSearchedColumn(dataIndex);
};
const handleReset = (clearFilters) => {
clearFilters();
setSearchText('');
};
/*
* @param dataIndex: 搜索的字段
* @param title: 搜索的字段中文名
* @param index2: 搜索的字段中的子字段
* */
const getColumnSearchProps = (dataIndex, title, index2 = null) => ({
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
<div style={{ padding: 8 }}>
<Input
ref={searchInput}
placeholder={`搜索${title}`}
value={selectedKeys[0]}
onChange={(e) => setSelectedKeys(e.target.value ? [e.target?.value.trim()] : [])}
onPressEnter={() => handleSearch(selectedKeys, confirm, dataIndex)}
style={{ width: 188, marginBottom: 8, display: 'block' }}
/>
<Button type="primary" onClick={() => handleSearch(selectedKeys, confirm, dataIndex)} icon="search" size="small" style={{ width: 90, marginRight: 8 }}>
查找
</Button>
<Button onClick={() => handleReset(clearFilters)} size="small" style={{ width: 90 }}>
重置
</Button>
</div>
),
filterIcon: (filtered) => <Icon type="search" style={{ color: filtered ? '#1890ff' : undefined }} />,
onFilter: (value, record) => {
if (index2) {
return record[dataIndex][index2]?.toString().toLowerCase().includes(value.toLowerCase());
}
return record[dataIndex]?.toString().toLowerCase().includes(value.toLowerCase());
},
onFilterDropdownVisibleChange: (visible) => {
if (visible) {
setTimeout(() => searchInput.current.select());
}
},
render: (text) => {
return searchedColumn === dataIndex ? <Highlighter highlightStyle={{ backgroundColor: '#ffc069', padding: 0 }} searchWords={[searchText]} autoEscape textToHighlight={text?.toString()} /> : text;
},
});
return { getColumnSearchProps };
};
export default useTableColumnSearch;