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

React三级联动表单实现 基于首选项从API获取二级下拉值问题

实现三级联动下拉选择器表单方案

现有代码问题修复

首先原有代码存在几处语法错误需先修正:

  • 箭头函数divstatus后多了多余的闭合大括号
  • 存在class和className混用的情况(React中DOM属性需统一使用className)
  • 两个下拉框重复使用了相同的id属性,不符合规范
  • 第一个下拉框默认选项值设置不合理,需选择具体捐赠类型后才触发展示后续下拉

实现思路

  • 扩充state状态管理:存储每一级下拉的选中值、后一级下拉的选项列表、控制后一级下拉的显隐状态
  • 第一级下拉选中后,调用后端接口获取第二级下拉的选项,同时渲染第二级下拉
  • 第二级下拉选中后,按需调用接口获取第三级下拉选项,渲染第三级下拉
  • 每一级未选中有效值时,后一级下拉默认隐藏

完整实现代码

import React from 'react';
import Section2 from '../Sections/Section2'
 
class App1 extends React.Component {
  // 初始化state
  constructor(props) {
    super(props);
    this.state = {
      // 第一级选中的捐赠类型
      selectedDonationType: '',
      // 第二级选项列表
      programOptions: [],
      // 第二级选中值
      selectedProgram: '',
      // 第三级选项列表
      thirdOptions: [],
      // 第三级选中值
      selectedThird: ''
    };
  }

  // 第一级下拉变更处理
  handleDonationTypeChange = async (e) => {
    const typeValue = e.target.value;
    this.setState({
      selectedDonationType: typeValue,
      // 切换第一级选项时重置后两级的状态
      selectedProgram: '',
      programOptions: [],
      selectedThird: '',
      thirdOptions: []
    });

    // 选中有效选项(非默认提示项)时调用接口拿第二级选项
    if (typeValue) {
      try {
        // 替换为你的实际后端接口地址,请求参数根据后端要求调整
        const res = await fetch(`/api/getPrograms?donationType=${typeValue}`);
        const data = await res.json();
        // 假设接口返回的选项数组格式为 [{value: '1', label: '项目1'}, ...]
        this.setState({
          programOptions: data
        })
      } catch (err) {
        console.error('获取项目列表失败', err);
      }
    }
  }

  // 第二级下拉变更处理
  handleProgramChange = async (e) => {
    const programValue = e.target.value;
    this.setState({
      selectedProgram: programValue,
      selectedThird: '',
      thirdOptions: []
    });

    if (programValue) {
      try {
        // 替换为你的实际后端接口地址,获取第三级下拉选项
        const res = await fetch(`/api/getThirdOptions?programId=${programValue}`);
        const data = await res.json();
        this.setState({
          thirdOptions: data
        })
      } catch (err) {
        console.error('获取第三级选项失败', err);
      }
    }
  }

  // 第三级下拉变更处理
  handleThirdChange = (e) => {
    this.setState({
      selectedThird: e.target.value
    })
  }

  render() {
    const { selectedDonationType, programOptions, selectedProgram, thirdOptions, selectedThird } = this.state;
    return (
        <>
          <div className="container">
          <header className="page-header">
              <h1 className="text-warning">Donate <i>Now</i></h1>
          </header>
          <form className="donation-form form-horizontal container" id="donation-form">
              {/* 第一级下拉:捐赠类型 */}
              <div id="donation-type-group" className="form-group">
                  <label htmlFor="donation_type">Donation Type <span className="required">*</span></label>
                  <select 
                    id="donation_type" 
                    onChange={this.handleDonationTypeChange} 
                    name="donation_type" 
                    className="form-control"
                    value={selectedDonationType}
                  >
                      <option value="">Select Donation Type</option>
                      <option value="hide">Sadaqa</option>
                      <option value="2">Fitrana</option>
                      <option value="3">Zakat</option>
                      <option value="4">Fidya</option>
                      <option value="5">Qurbani</option>
                      <option value="6">Donation</option>
                      <option value="15">Kaffara</option>
                  </select>
              </div>

              {/* 第二级下拉:项目,第一级选中后才展示 */}
              {selectedDonationType && programOptions.length > 0 && (
                <div id="program-group" className="form-group">
                    <label htmlFor="program">Programs<span className="required">*</span></label>
                    <select 
                      id="program" 
                      name="program" 
                      className="form-control"
                      value={selectedProgram}
                      onChange={this.handleProgramChange}
                    >
                        <option value="">Select Program</option>
                        {programOptions.map(item => (
                          <option key={item.value} value={item.value}>{item.label}</option>
                        ))}
                    </select>
                </div>
              )}

              {/* 第三级下拉,第二级选中后才展示 */}
              {selectedProgram && thirdOptions.length > 0 && (
                <div id="third-group" className="form-group">
                    <label htmlFor="third_select">第三级选项<span className="required">*</span></label>
                    <select 
                      id="third_select" 
                      name="third_select" 
                      className="form-control"
                      value={selectedThird}
                      onChange={this.handleThirdChange}
                    >
                        <option value="">请选择</option>
                        {thirdOptions.map(item => (
                          <option key={item.value} value={item.value}>{item.label}</option>
                        ))}
                    </select>
                </div>
              )}

              <div className="text-center">
                  <button type="submit" className="btn btn-lg btn-primary">Submit donation</button>
              </div>
          </form>
          <hr/>
          <Section2 />
      </div>
      </>
  )
}
}
export default App1;

关键说明

  • 接口请求部分你可以根据实际技术栈替换为axios等请求库,参数和返回值处理按照后端实际约定调整即可
  • 如果不需要第三级下拉的接口请求,也可以直接根据第二级选中值匹配本地预设的选项列表
  • 可选添加加载状态,接口请求过程中展示加载提示提升用户体验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 11:36:02