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

如何基于@shoutem/ui DropDownMenu实现联动多级选择?

解决@shoutem/ui DropDownMenu联动选择的错误问题

我仔细看了你的代码和报错信息,这个错误的核心原因是状态管理混乱,以及第二个DropDownMenu的selectedOption和onOptionSelected配置错误,导致选中的选项不在下拉菜单的选项列表里。下面一步步给你分析和修复:

问题根源

  1. 你没有单独维护「选中城市」的状态,而是把选中的城市赋值给了selectedZone,这直接覆盖了之前选中的区域对象,导致后续第二个下拉菜单的options(来自selectedZone.children)和selectedOption(被改成了城市对象)完全不匹配。
  2. 第二个DropDownMenu的selectedOption错误地设置成了区域对象,而不是城市列表中的某一项。
  3. valueProperty配置有误:不管是区域还是城市的下拉菜单,你都用了"cars.model",但你的数据结构里根本没有这个字段,应该用每个选项的唯一标识(比如id)。

修复步骤和完整代码

1. 完善状态管理

新增selectedCity状态,单独维护选中的城市,避免和区域状态混淆;同时在组件挂载时初始化默认选中项。

2. 修正下拉菜单配置

调整第一个下拉菜单的选择事件,切换区域时自动重置选中城市;修正第二个下拉菜单的selectedOption和onOptionSelected绑定,确保选中项来自当前区域的城市列表。

import React, { Component } from 'react';
import { View } from 'react-native';
import { DropDownMenu, Text, Screen } from '@shoutem/ui';

class TestConfirm extends Component {
  constructor(props) {
    super(props);
    this.state = {
      zone: [
        {
          id: 0,
          brand: "North",
          models: {
            model: "Audi R8",
            image: { url: "https://shoutem.github.io/img/ui-toolkit/dropdownmenu/Audi-R8.jpg" },
            description: "North Description"
          },
          children: [{ name: "N1", id: 10 }, { name: "N2", id: 17 }]
        },
        {
          id: 1,
          brand: "West",
          models: {
            model: "Chiron",
            image: { url: "https://shoutem.github.io/img/ui-toolkit/dropdownmenu/Chiron.jpg" },
            description: "West Description"
          },
          children: [{ name: "W1", id: 10 }, { name: "W2", id: 17 }]
        },
        {
          id: 2,
          brand: "East",
          models: {
            model: "Dodge Viper",
            image: { url: "https://shoutem.github.io/img/ui-toolkit/dropdownmenu/Dodge-Viper.jpg" },
            description: "East Description"
          },
          children: [{ name: "E1", id: 10 }, { name: "E2", id: 17 }]
        },
      ],
      selectedZone: null,
      selectedCity: null
    };
  }

  componentDidMount() {
    // 组件挂载后初始化默认选中项
    const defaultZone = this.state.zone[0];
    this.setState({
      selectedZone: defaultZone,
      selectedCity: defaultZone.children[0]
    });
  }

  render() {
    const { selectedZone, selectedCity } = this.state;
    // 处理初始化前的空值,避免渲染报错
    if (!selectedZone || !selectedCity) {
      return null;
    }

    return (
      <Screen>
        <DropDownMenu
          styleName="horizontal"
          options={this.state.zone}
          selectedOption={selectedZone}
          onOptionSelected={(zone) => {
            this.setState({
              selectedZone: zone,
              selectedCity: zone.children[0] // 切换区域后自动选中第一个城市
            });
          }}
          titleProperty="brand"
          valueProperty="id" // 用唯一id匹配选项,避免引用不一致问题
        />
        <Text styleName="md-gutter-horizontal">
          {selectedZone.models.description}
        </Text>
        <DropDownMenu
          styleName="horizontal"
          options={selectedZone.children}
          selectedOption={selectedCity}
          onOptionSelected={(city) => {
            this.setState({ selectedCity: city }); // 仅更新选中的城市状态
          }}
          titleProperty="name"
          valueProperty="id" // 城市的唯一标识
        />
      </Screen>
    );
  }
}

export default TestConfirm;

额外说明

  • 我添加了componentDidMount来初始化状态,避免在constructor中直接访问this.state可能出现的问题
  • 将两个下拉菜单的valueProperty都设置为id,这符合shoutem/ui的设计逻辑:用唯一值匹配选项,彻底解决「选中项不在选项列表」的报错
  • 增加了空值判断,防止组件挂载初期状态未初始化导致的渲染错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:33:07