React结合Core API实现数据库驱动的国家省市三级联动下拉如何实现
国家/省份/城市三级联动实现方案(React + ASP.NET Core API)
一、后端ASP.NET Core API实现
- 先设计数据库区域表基础结构,至少包含
id、name、parent_id、level四个字段,level字段用来区分层级:1对应国家、2对应省份、3对应城市 - 编写三个基础查询接口,返回格式统一为JSON,单条数据至少包含
value(区域ID)、label(区域名称)两个字段,可直接适配前端下拉组件的选项格式:- 获取所有国家接口:
GET /api/area/countries,返回所有level=1的区域列表 - 根据国家ID获取对应省份接口:
GET /api/area/provinces?countryId={国家ID},返回parent_id等于传入国家ID、level=2的区域列表 - 根据省份ID获取对应城市接口:
GET /api/area/cities?provinceId={省份ID},返回parent_id等于传入省份ID、level=3的区域列表
- 获取所有国家接口:
提示:如果数据量不大,也可以只写一个全量区域查询接口,所有过滤逻辑放在前端处理,减少接口请求次数
二、前端React实现
以下是基于React Hooks + Ant Design Select组件的实现示例,不用组件库的话替换为原生select标签即可:
import { useState, useEffect } from 'react'; import { Select } from 'antd'; const RegionCascader = () => { // 各层级选项列表状态 const [countryList, setCountryList] = useState([]); const [provinceList, setProvinceList] = useState([]); const [cityList, setCityList] = useState([]); // 各层级选中值状态 const [selectedCountry, setSelectedCountry] = useState(null); const [selectedProvince, setSelectedProvince] = useState(null); const [selectedCity, setSelectedCity] = useState(null); // 页面初始化拉取全部国家列表 useEffect(() => { fetch('/api/area/countries') .then(res => res.json()) .then(data => setCountryList(data)) .catch(err => console.log('国家列表加载失败', err)); }, []); // 选中国家后拉取对应省份列表,同时清空下级选中值和选项 useEffect(() => { if (!selectedCountry) { setProvinceList([]); setSelectedProvince(null); return; } fetch(`/api/area/provinces?countryId=${selectedCountry}`) .then(res => res.json()) .then(data => setProvinceList(data)) .catch(err => console.log('省份列表加载失败', err)); }, [selectedCountry]); // 选中省份后拉取对应城市列表,同时清空下级选中值和选项 useEffect(() => { if (!selectedProvince) { setCityList([]); setSelectedCity(null); return; } fetch(`/api/area/cities?provinceId=${selectedProvince}`) .then(res => res.json()) .then(data => setCityList(data)) .catch(err => console.log('城市列表加载失败', err)); }, [selectedProvince]); return ( <div style={{ display: 'flex', gap: '16px' }}> <Select placeholder="选择国家" value={selectedCountry} onChange={val => setSelectedCountry(val)} options={countryList} style={{ width: 180 }} /> <Select placeholder="选择省份" value={selectedProvince} onChange={val => setSelectedProvince(val)} options={provinceList} style={{ width: 180 }} disabled={!selectedCountry} /> <Select placeholder="选择城市" value={selectedCity} onChange={val => setSelectedCity(val)} options={cityList} style={{ width: 180 }} disabled={!selectedProvince} /> </div> ); }; export default RegionCascader;
- 未选择上级时下级下拉默认禁用,避免无效操作
- 可根据业务需求对已经拉取过的省份、城市数据做本地缓存,避免重复请求接口
内容的提问来源于stack exchange,提问作者Akilagopal
相关产品推荐
相关产品推荐

