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

React JS实现下拉框联动:根据性别筛选对应姓名

React多组联动下拉框实现方案

原代码问题梳理

  • 状态命名混淆:name状态实际存储的是性别ID,易引发误解
  • 直接在组件体调用setState:会触发无限重渲染
  • 多组下拉框共用同一状态:各组选中值会互相干扰
  • 性别下拉框显示不直观:直接展示数字ID而非“Male/Female”文本
  • 无联动过滤逻辑:姓名下拉框未根据选中性别筛选选项

修正后的完整代码

import React, { useState } from 'react';
import { Box, TextField, MenuItem } from '@mui/material';

// 原始人员数据(放在组件外部避免重复创建)
const personData = [
  { Field_ID: 1, FieldName_CR: "Sohan", gender_ID: 1, male: "Male" },
  { Field_ID: 2, FieldName_CR: "Mohan", gender_ID: 1, male: "Male" },
  { Field_ID: 3, FieldName_CR: "Gaurav", gender_ID: 1, male: "Male" },
  { Field_ID: 4, FieldName_CR: "Hakim", gender_ID: 1, male: "Male" },
  { Field_ID: 5, FieldName_CR: "Sumit", gender_ID: 1, male: "Male" },
  { Field_ID: 9, FieldName_CR: "Neha", gender_ID: 2, female: "Female" },
  { Field_ID: 10, FieldName_CR: "Seema", gender_ID: 2, female: "Female" },
  { Field_ID: 11, FieldName_CR: "Anuradha", gender_ID: 2, female: "Female" },
  { Field_ID: 12, FieldName_CR: "Meenu", gender_ID: 2, female: "Female" },
  { Field_ID: 13, FieldName_CR: "Harsha", gender_ID: 2, female: "Female" }
];

// 整理后的性别选项(关联ID与显示文本)
const genderOptions = [
  { id: 1, label: 'Male' },
  { id: 2, label: 'Female' }
];

const MultiGroupDropdown = () => {
  // 初始化两组下拉框的独立状态,每组维护自己的性别和姓名选中值
  const [groups, setGroups] = useState([
    { gender: '', name: '' },
    { gender: '', name: '' }
  ]);

  // 处理下拉框值变化的通用函数
  const handleGroupChange = (groupIndex, field, value) => {
    const updatedGroups = [...groups];
    updatedGroups[groupIndex][field] = value;
    // 切换性别时清空对应组的姓名选择,避免无效值残留
    if (field === 'gender') {
      updatedGroups[groupIndex].name = '';
    }
    setGroups(updatedGroups);
  };

  return (
    <>
      {/* 第一组下拉框 */}
      <Box sx={{ display: 'flex', gap: 2, marginBottom: 2 }}>
        <TextField
          className="ruleContainer"
          select
          label="Gender"
          variant="outlined"
          size="small"
          value={groups[0].gender}
          onChange={(e) => handleGroupChange(0, 'gender', e.target.value)}
        >
          <MenuItem value="">请选择性别</MenuItem>
          {genderOptions.map(opt => (
            <MenuItem key={opt.id} value={opt.id}>
              {opt.label}
            </MenuItem>
          ))}
        </TextField>

        <TextField
          className="ruleContainer"
          select
          label="Name"
          variant="outlined"
          size="small"
          value={groups[0].name}
          onChange={(e) => handleGroupChange(0, 'name', e.target.value)}
          disabled={!groups[0].gender} {/* 未选性别时禁用姓名框 */}
        >
          <MenuItem value="">请选择姓名</MenuItem>
          {/* 根据选中的性别过滤姓名选项 */}
          {personData
            .filter(person => person.gender_ID === groups[0].gender)
            .map(person => (
              <MenuItem key={person.Field_ID} value={person.FieldName_CR}>
                {person.FieldName_CR}
              </MenuItem>
            ))}
        </TextField>
      </Box>

      {/* 第二组下拉框 */}
      <Box sx={{ display: 'flex', gap: 2 }}>
        <TextField
          className="ruleContainer"
          select
          label="Gender"
          variant="outlined"
          size="small"
          value={groups[1].gender}
          onChange={(e) => handleGroupChange(1, 'gender', e.target.value)}
        >
          <MenuItem value="">请选择性别</MenuItem>
          {genderOptions.map(opt => (
            <MenuItem key={opt.id} value={opt.id}>
              {opt.label}
            </MenuItem>
          ))}
        </TextField>

        <TextField
          className="ruleContainer"
          select
          label="Name"
          variant="outlined"
          size="small"
          value={groups[1].name}
          onChange={(e) => handleGroupChange(1, 'name', e.target.value)}
          disabled={!groups[1].gender}
        >
          <MenuItem value="">请选择姓名</MenuItem>
          {personData
            .filter(person => person.gender_ID === groups[1].gender)
            .map(person => (
              <MenuItem key={person.Field_ID} value={person.FieldName_CR}>
                {person.FieldName_CR}
              </MenuItem>
            ))}
        </TextField>
      </Box>
    </>
  );
};

export default MultiGroupDropdown;

关键改动说明

  1. 独立状态管理:用groups数组存储每组的选中值,确保各组状态互不干扰
  2. 联动过滤逻辑:姓名下拉框通过filter方法,根据当前组选中的性别ID筛选对应人员
  3. 用户体验优化:添加默认提示选项、未选性别时禁用姓名框、切换性别自动清空已选姓名
  4. 代码规范优化:使用唯一的Field_ID作为MenuItem的key,避免React警告
  5. 数据清晰化:整理性别选项为ID+文本的结构,替代原代码中直接显示数字ID的逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 10:40:35