如何用TypeScript实现城市文章按首字母分组排序并正确渲染?
解决方案
1. 先搞定类型定义(解决类型问题)
先明确城市数据的TS类型,从根源避免类型报错:
interface City { id: number; cityName: string; articleUrl: string; }
2. 修复排序与分组逻辑(解决排序失效问题)
排序失效大概率是没处理大小写,或是分组时首字母提取不统一。下面是可靠的分组排序函数:
// 按城市名首字母分组并排序 const groupAndSortCities = (cities: City[]): Record<string, City[]> => { // 先按城市名称(忽略大小写)排序 const sortedCities = [...cities].sort((a, b) => a.cityName.localeCompare(b.cityName, undefined, { sensitivity: 'base' }) ); // 分组 return sortedCities.reduce((groups, city) => { // 提取首字母并转大写,统一格式避免分组重复 const firstLetter = city.cityName.trim().charAt(0).toUpperCase(); // 存在分组则追加,不存在则创建新分组 groups[firstLetter] = groups[firstLetter] ? [...groups[firstLetter], city] : [city]; return groups; }, {} as Record<string, City[]>); };
- 用
localeCompare并设置sensitivity: 'base',确保忽略大小写和重音符号,排序更准确。 - 提取首字母前先
trim(),避免城市名前缀空格导致的分组错误。
3. 修复React渲染逻辑(解决渲染错误)
渲染时要保证key的唯一性,同时正确遍历分组后的结构:
import React from 'react'; interface CityListProps { cities: City[]; } const CityList: React.FC<CityListProps> = ({ cities }) => { const groupedCities = groupAndSortCities(cities); // 将分组首字母按A-Z顺序排序 const sortedLetters = Object.keys(groupedCities).sort(); return ( <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 p-4"> {sortedLetters.map(letter => ( <div key={letter} className="bg-gray-50 p-4 rounded-lg shadow-sm"> <h3 className="font-bold text-lg mb-3">{letter}</h3> <ul className="space-y-2"> {groupedCities[letter].map(city => ( <li key={city.id}> <a href={city.articleUrl} className="text-blue-600 hover:underline" target="_blank" rel="noopener noreferrer" > {city.cityName} </a> </li> ))} </ul> </div> ))} </div> ); }; export default CityList;
- 外层分组用
letter作为key,内层城市用唯一的city.id作为key,避免React key警告或渲染错误。 - 用Tailwind的
grid类实现响应式多列布局,适配不同屏幕尺寸。
4. 常见问题排查
- 排序仍异常:检查城市名称是否包含特殊前缀(如括号、符号),可在提取首字母前过滤非字母字符。
- 渲染报错:确认
groupedCities每个分组都是数组,且city.id为唯一值,不要用数组索引当key。 - 类型报错:确保后端返回的字段名与
City接口一致,比如不要把cityName写成name。
内容的提问来源于stack exchange,提问作者aries0152
相关产品推荐
相关产品推荐

