react实现级联
实现级联选择器的基本思路
级联选择器通常用于处理具有层级关系的数据,例如省市区选择。React中可以通过状态管理和组件联动实现这一功能。
数据结构的组织
采用嵌套结构或扁平化结构存储级联数据。嵌套结构更适合展示父子关系:
const data = [
{
id: 1,
name: '北京',
children: [
{ id: 11, name: '海淀区' },
{ id: 12, name: '朝阳区' }
]
}
]
状态管理方案
使用useState或useReducer管理当前选择的各级数据:
const [selectedValues, setSelectedValues] = useState({
level1: null,
level2: null,
level3: null
});
组件联动实现
创建多个关联的选择器组件,下级选择器根据上级选择结果动态渲染:
function Cascader({ data }) {
const [selected, setSelected] = useState({});
const handleChange = (level, value) => {
setSelected(prev => ({
...prev,
[level]: value,
// 清空下级选择
...Object.fromEntries(
Object.keys(prev)
.filter(key => parseInt(key.replace('level', '')) > parseInt(level.replace('level', '')))
.map(key => [key, null])
)
}));
};
return (
<div>
<Select
options={data}
onChange={(value) => handleChange('level1', value)}
/>
{selected.level1 && (
<Select
options={data.find(item => item.id === selected.level1)?.children || []}
onChange={(value) => handleChange('level2', value)}
/>
)}
</div>
);
}
性能优化建议
对于大数据量的级联选择,可采用以下优化方案:
- 虚拟滚动技术处理长列表
- 异步加载下级数据
- 使用React.memo避免不必要的渲染
完整示例代码
import React, { useState } from 'react';
const Cascader = ({ data }) => {
const [selected, setSelected] = useState({
province: null,
city: null,
district: null
});
const handleProvinceChange = (value) => {
setSelected({
province: value,
city: null,
district: null
});
};
const handleCityChange = (value) => {
setSelected(prev => ({
...prev,
city: value,
district: null
}));
};
const currentProvince = data.find(p => p.id === selected.province);
const currentCity = currentProvince?.children?.find(c => c.id === selected.city);
return (
<div className="cascader">
<select
value={selected.province || ''}
onChange={(e) => handleProvinceChange(e.target.value)}
>
<option value="">选择省份</option>
{data.map(province => (
<option key={province.id} value={province.id}>
{province.name}
</option>
))}
</select>
{selected.province && (
<select
value={selected.city || ''}
onChange={(e) => handleCityChange(e.target.value)}
>
<option value="">选择城市</option>
{currentProvince.children.map(city => (
<option key={city.id} value={city.id}>
{city.name}
</option>
))}
</select>
)}
{selected.city && (
<select
value={selected.district || ''}
onChange={(e) => setSelected(prev => ({...prev, district: e.target.value}))}
>
<option value="">选择区县</option>
{currentCity.children.map(district => (
<option key={district.id} value={district.id}>
{district.name}
</option>
))}
</select>
)}
</div>
);
};
第三方库推荐
对于复杂场景,可以考虑以下成熟方案:
- antd Cascader组件
- rc-cascader
- react-cascader
这些库提供了丰富的功能如异步加载、搜索过滤、自定义渲染等。







