
本文介绍如何将多层嵌套的州-城市 json 数据扁平化,并基于动态 url 参数(如城市名)精准匹配,一次性获取城市名称、所属州全称、州缩写 id 及描述信息,适用于 react 单页应用中的城市详情页开发。
本文介绍如何将多层嵌套的州-城市 json 数据扁平化,并基于动态 url 参数(如城市名)精准匹配,一次性获取城市名称、所属州全称、州缩写 id 及描述信息,适用于 react 单页应用中的城市详情页开发。
在处理类似美国各州及其下属城市的嵌套 JSON 数据时,直接使用 map().filter() 容易产生二维数组(如 [[], [{...}]]),导致后续取值困难且逻辑冗余。更优雅、高效的方案是先扁平化再过滤——利用 Array.prototype.flatMap() 将深层结构“拉平”为单一维度的城市对象列表,每个对象都携带完整的上下文信息(州名、州 ID、城市名、描述)。
以下为完整实现步骤:
✅ 第一步:数据扁平化(预处理一次,复用多次)
// 假设 stateNames 来自 ./states.json 或其他数据源
const allPlaces = stateNames.flatMap(({ state, id, places }) =>
places.map((place) => ({
city: place.city,
description: place.description,
stateName: state.trim(), // 清理首尾空格(如 "Illinois " → "Illinois")
stateId: id,
}))
);
该操作将原始嵌套结构转换为如下扁平数组:
[
{ city: "Ames", description: "ames-description", stateName: "Iowa", stateId: "IA" },
{ city: "Davenport ", description: "davenport-description", stateName: "Iowa", stateId: "IA" },
{ city: "Chicago", description: "chicago-description", stateName: "Illinois", stateId: "IL" },
{ city: "Elgin ", description: "elgin-description", stateName: "Illinois", stateId: "IL" },
// ...
]
✅ 第二步:动态过滤(响应路由参数)
在 React 组件中,结合 useParams 获取 URL 中的城市名(如 /city/Elgin),并执行精确匹配(注意 .trim() 处理原始数据中的空格):
import { useParams } from 'react-router-dom';
import stateNames from './states.json';
const allPlaces = stateNames.flatMap(({ state, id, places }) =>
places.map((place) => ({
city: place.city,
description: place.description,
stateName: state.trim(),
stateId: id,
}))
);
const CityDetailsPage = () => {
const { cityname } = useParams();
// 精确匹配(忽略 city 字段末尾空格)
const matches = allPlaces.filter(
(place) => place.city.trim() === cityname
);
// 若无匹配,可渲染友好提示
if (matches.length === 0) {
return <p>未找到城市:{cityname}</p>;
}
return (
{matches.map((place, idx) => (
<div key="{idx}">
<p>
<strong>{place.city.trim()}, {place.stateId}</strong><br>
{place.stateName}<br>
{place.description}
</p>
</div>
))}
>
);
};
export default CityDetailsPage;
⚠️ 注意事项
-
空格处理:原始 JSON 中
"Elgin "含尾部空格,务必使用.trim()进行标准化比对,否则===会失败; -
类型安全:建议为
useParams添加泛型(如),避免undefined风险; -
性能优化:
allPlaces可定义在组件外部或使用useMemo缓存,避免重复计算; - 错误边界:生产环境应增加空数据/404 处理逻辑,提升用户体验。
通过此方案,你不仅能准确返回 Elgin, IL、Illinois 和 elgin-description,还能轻松扩展支持多城市同名场景(如多个州存在 “Springfield”),真正实现高内聚、低耦合的数据检索逻辑。











