如何使用@atlaskit/select实现级联异步选择器?
用@atlaskit/select实现级联异步选择器的解决方案
核心问题分析
你之前把城市选项数组cities直接赋值给第二个AsyncSelect的loadOptions,但@atlaskit的AsyncSelect要求loadOptions必须是返回Promise的函数,这就是数据能打印但渲染不出来的原因。
实现思路
- 国家选择器正常用异步函数加载选项,切换时触发城市数据的获取
- 城市选择器的
loadOptions包装成返回Promise的函数,内部返回已缓存的城市数组 - 切换国家时清空城市的选中状态,避免旧数据残留
- 未选择国家时禁用城市选择器,提升体验
完整示例代码
import { useState } from 'react'; import { AsyncSelect } from '@atlaskit/select'; // 模拟获取国家列表的异步接口 const fetchCountries = async () => { return new Promise(resolve => { setTimeout(() => { resolve([ { label: '中国', value: 'CN' }, { label: '美国', value: 'US' }, { label: '日本', value: 'JP' }, ]); }, 500); }); }; // 模拟根据国家ID获取城市的异步接口 const fetchCitiesByCountry = async (countryId) => { const cityMap = { CN: [ { label: '北京', value: 'CN-BJ' }, { label: '上海', value: 'CN-SH' }, { label: '广州', value: 'CN-GZ' }, ], US: [ { label: '纽约', value: 'US-NY' }, { label: '洛杉矶', value: 'US-LA' }, { label: '芝加哥', value: 'US-CH' }, ], JP: [ { label: '东京', value: 'JP-TK' }, { label: '大阪', value: 'JP-OS' }, ], }; return new Promise(resolve => { setTimeout(() => { resolve(cityMap[countryId] || []); }, 500); }); }; const CascadingSelect = () => { const [selectedCountry, setSelectedCountry] = useState(null); const [cities, setCities] = useState([]); const [selectedCity, setSelectedCity] = useState(null); // 切换国家时的处理逻辑 const handleCountryChange = (option) => { setSelectedCountry(option); setSelectedCity(null); // 清空已选城市 // 调用接口获取对应城市 fetchCitiesByCountry(option.value).then(data => { setCities(data); }); }; // 城市选择器的loadOptions函数,必须返回Promise const loadCityOptions = async () => { return cities; }; return ( <div style={{ padding: '20px', maxWidth: '400px' }}> <div style={{ marginBottom: '16px' }}> <label style={{ display: 'block', marginBottom: '8px' }}>选择国家</label> <AsyncSelect loadOptions={fetchCountries} onChange={handleCountryChange} value={selectedCountry} placeholder="请选择国家" isClearable /> </div> <div> <label style={{ display: 'block', marginBottom: '8px' }}>选择城市</label> <AsyncSelect loadOptions={loadCityOptions} onChange={(option) => setSelectedCity(option)} value={selectedCity} placeholder="请先选择国家" isDisabled={!selectedCountry} isClearable /> </div> </div> ); }; export default CascadingSelect;
关键注意点
- 城市选择器的
loadOptions必须是异步函数,哪怕数据已经缓存好,也要返回Promise - 切换国家时一定要清空城市选中值,避免出现国家和城市不匹配的情况
- 给城市选择器加
isDisabled属性,未选国家时禁用,减少用户误操作
内容的提问来源于stack exchange,提问作者Fran b
相关产品推荐
相关产品推荐

