You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中JSON数据联动展示问题:Picker与DropDown修复

React Native 路由与城市联动组件实现

我有如下JSON数据,需要在React Native应用中实现联动功能:

[
  {
    "001": [
      {
        "index": 0,
        "fare": 0,
        "city": "Colombo"
      },
      {
        "index": 1,
        "fare": 30,
        "city": "Maligawaththa"
      },
      {
        "index": 2,
        "fare": 38,
        "city": "Kelanithissa"
      },
      {
        "index": 3,
        "fare": 50,
        "city": "4 Kanuwa / Biyagama road"
      },
      {
        "index": 4,
        "fare": 61,
        "city": "Thorana Junction"
      },
      {
        "index": 5,
        "fare": 73,
        "city": "Kelaniya University"
      }
    ]
  },
  {
    "100": [
      {
        "index": 0,
        "fare": "446.00",
        "city": "Mulgampola"
      },
      {
        "index": 1,
        "fare": "452.00",
        "city": "Kandy"
      }
    ]
  },
  {
    "101": [
      {
        "index": 0,
        "fare": "446.00",
        "city": "Mulgampola"
      },
      {
        "index": 1,
        "fare": "452.00",
        "city": "Kandy"
      }
    ]
  }
]

需求:

  • 在Picker组件中展示每个对象的键(如001、100、101)
  • 用户选择某个路由后,在独立的DropDown组件中显示该路由对应的城市列表

我尝试了以下TypeScript代码,但无法实现联动功能,需要修正:

const keys = data.map((item) => Object.keys(item)[0]);

const cities = data.flatMap((item: any) => {
  const routeNumber = Object.keys(item)[0];
  return item[routeNumber].map((subItem: any) => ({
    label: subItem.city,
    value: subItem.index,
  }));
});

问题分析与修正方案

你的代码问题在于:将所有路由的城市合并成了一个数组,没有和选中的路由建立关联,无法实现"选路由→显示对应城市"的联动逻辑。

以下是完整的修正实现,包含类型定义、状态管理和组件联动逻辑:

1. 定义类型(避免any类型)

// 城市数据类型
interface CityItem {
  index: number;
  fare: number | string;
  city: string;
}

// 转换后的路由映射类型
type RouteMap = Record<string, CityItem[]>;

2. 转换原始数据为更易用的结构

先把原始数组转换成键为路由编号、值为对应城市数组的对象,方便后续快速查找:

const rawData = [/* 你的JSON数据 */];

// 转换为路由映射
const routeMap: RouteMap = rawData.reduce((acc, item) => {
  const routeKey = Object.keys(item)[0];
  acc[routeKey] = item[routeKey];
  return acc;
}, {} as RouteMap);

// 获取所有路由编号列表
const routeOptions = Object.keys(routeMap);

3. 完整组件实现

使用React状态管理选中的路由,动态生成对应城市的下拉选项:

import React, { useState } from 'react';
import { View, Picker, StyleSheet } from 'react-native';
// 这里使用react-native-dropdown-picker作为下拉组件,可替换为你项目中的组件
import DropDownPicker from 'react-native-dropdown-picker';

// 类型定义
interface CityItem {
  index: number;
  fare: number | string;
  city: string;
}
type RouteMap = Record<string, CityItem[]>;

const RouteCityPicker = () => {
  // 原始数据
  const rawData = [
    {
      "001": [
        { "index": 0, "fare": 0, "city": "Colombo" },
        { "index": 1, "fare": 30, "city": "Maligawaththa" },
        { "index": 2, "fare": 38, "city": "Kelanithissa" },
        { "index": 3, "fare": 50, "city": "4 Kanuwa / Biyagama road" },
        { "index": 4, "fare": 61, "city": "Thorana Junction" },
        { "index": 5, "fare": 73, "city": "Kelaniya University" }
      ]
    },
    {
      "100": [
        { "index": 0, "fare": "446.00", "city": "Mulgampola" },
        { "index": 1, "fare": "452.00", "city": "Kandy" }
      ]
    },
    {
      "101": [
        { "index": 0, "fare": "446.00", "city": "Mulgampola" },
        { "index": 1, "fare": "452.00", "city": "Kandy" }
      ]
    }
  ];

  // 转换为路由映射
  const routeMap: RouteMap = rawData.reduce((acc, item) => {
    const routeKey = Object.keys(item)[0];
    acc[routeKey] = item[routeKey];
    return acc;
  }, {} as RouteMap);

  const routeOptions = Object.keys(routeMap);

  // 状态管理:选中的路由编号、选中的城市、下拉框展开状态
  const [selectedRoute, setSelectedRoute] = useState<string>(routeOptions[0]);
  const [selectedCity, setSelectedCity] = useState<number>(0);
  const [cityOpen, setCityOpen] = useState(false);

  // 根据选中的路由动态生成城市选项
  const cityOptions = routeMap[selectedRoute].map(city => ({
    label: city.city,
    value: city.index
  }));

  return (
    <View style={styles.container}>
      {/* 路由选择Picker */}
      <Picker
        selectedValue={selectedRoute}
        style={styles.picker}
        onValueChange={(itemValue) => {
          setSelectedRoute(itemValue);
          // 切换路由时重置城市选择为第一个选项
          setSelectedCity(routeMap[itemValue][0].index);
        }}
      >
        {routeOptions.map(route => (
          <Picker.Item key={route} label={route} value={route} />
        ))}
      </Picker>

      {/* 城市下拉组件 */}
      <DropDownPicker
        open={cityOpen}
        value={selectedCity}
        items={cityOptions}
        setOpen={setCityOpen}
        setValue={setSelectedCity}
        style={styles.dropdown}
        placeholder="选择城市"
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    padding: 20,
    gap: 15
  },
  picker: {
    height: 50,
    borderWidth: 1,
    borderColor: '#ccc',
    borderRadius: 8
  },
  dropdown: {
    height: 50,
    borderWidth: 1,
    borderColor: '#ccc',
    borderRadius: 8
  }
});

export default RouteCityPicker;

关键修正点

  • 将原始数据转换为RouteMap结构,通过路由编号可直接获取对应城市列表,避免重复遍历
  • 使用useState管理选中状态,路由变化时自动更新城市选项并重置选中城市
  • 移除了合并所有城市的flatMap逻辑,改为根据选中路由动态生成城市选项

内容的提问来源于stack exchange,提问作者Movindu G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 23:20:54