当前位置:首页 > React

react实现级联

2026-01-26 15:08:31React

实现级联选择器的基本思路

级联选择器通常用于处理具有层级关系的数据,例如省市区选择。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
});

组件联动实现

创建多个关联的选择器组件,下级选择器根据上级选择结果动态渲染:

react实现级联

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

这些库提供了丰富的功能如异步加载、搜索过滤、自定义渲染等。

标签: 级联react
分享给朋友:

相关文章

react如何发音

react如何发音

React的发音 React的正确发音为 /riˈækt/,类似于“ree-akt”。以下是详细说明: 发音分解 第一个音节“Ree”发音类似英文单词“see”中的“ee”音。…

react如何减少setState

react如何减少setState

减少 React 中 setState 调用的方法 合并多次状态更新 使用函数式更新方式合并多次 setState 调用。React 会将多次状态更新批量处理,避免不必要的重新渲染。 // 非函…

react如何代码优化

react如何代码优化

减少不必要的重新渲染 使用 React.memo 包装函数组件以避免在 props 未变化时重新渲染。对于类组件,可以通过 shouldComponentUpdate 或继承 PureComponen…

如何实操react

如何实操react

安装 React 环境 使用 create-react-app 快速搭建项目: npx create-react-app my-app cd my-app npm start 项目启动后默认在…

react项目如何调试

react项目如何调试

使用浏览器开发者工具 React项目调试最直接的方法是使用浏览器内置的开发者工具(Chrome DevTools/Firefox Developer Tools)。打开开发者工具后,切换到“Sourc…

react如何编码参数

react如何编码参数

编码参数的方法 在React中,编码参数通常涉及URL查询参数或路由参数的编码和解码。以下是几种常见场景的处理方法: URL查询参数编码 使用encodeURIComponent对参数进行编码,避免…