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

如何使用React Hook实现级联下拉?基于.NET Core后端的实现求助

实现级联下拉菜单的修改建议

现有代码的核心问题

  • useState命名逻辑错误,useState返回值的第一个参数是状态值,第二个才是状态更新方法,你写反了
  • 监听经销商加载的useEffect依赖为空数组,只会在页面初始化时触发一次,不会跟着选中的zone值变化
  • 请求经销商接口没有携带选中的zoneId参数,后端无法过滤对应数据
  • 下拉框顺序不合理,应该先选zone再选dealer,操作逻辑更顺畅
  • MenuItem没有加唯一key属性,会触发React控制台警告

前端React代码修改

1. 修正状态定义与zone列表加载逻辑

// 修正useState命名
const [zoneList, setZoneList] = useState([]);
const [dealerList, setDealerList] = useState([]);

// 页面初始化加载所有zone选项
useEffect(() => {
  fetch('http://localhost:61808/api/Zone', {
    method: 'GET',
    headers: {
      'Content-Type': 'application/json',
    }
  })
  .then(resp => resp.json())
  .then(resp => setZoneList(resp))
  .catch(err => console.error('加载区域列表失败:', err))
}, [])

2. 新增级联加载dealer的逻辑

// 监听选中的zoneId变化,动态加载对应经销商列表
useEffect(() => {
  // 只有选中了有效zoneId才发起请求
  if(values.zoneId) {
    // 将选中的zoneId作为查询参数传给后端
    fetch(`http://localhost:61808/api/Dealer?zoneId=${values.zoneId}`, {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
      }
    })
    .then(resp => resp.json())
    .then(resp => {
      setDealerList(resp)
      // zone切换时清空之前选中的经销商值
      values.dealerId = ''
    })
    .catch(err => console.error('加载经销商列表失败:', err))
  } else {
    // 未选中zone时清空经销商列表和选中值
    setDealerList([])
    values.dealerId = ''
  }
}, [values.zoneId]) // 依赖设置为选中的zoneId,每次zone变化自动触发

3. 修正JSX渲染逻辑

return (
  <form autoComplete="off" noValidate className={classes.root} onSubmit={handleSubmit}>
    {/* 把Zone选择框放在前面,符合操作顺序 */}
    <InputLabel style={{ display: 'block' }} className={classes.FormControl}>Zone</InputLabel>
    <FormControl variant="outlined" className={classes.FormControl}>
      <Select 
        name="zoneId"
        value={values.zoneId}
        onChange={handleInputChange}
      >
        <MenuItem value="">Select Zone</MenuItem>
        {
          zoneList.map(x => (
            <MenuItem key={x.id} value={x.id}>{x.name}</MenuItem>
          ))
        }
      </Select>
    </FormControl>

    <InputLabel style={{ display: 'block' }} className={classes.FormControl}>Dealer Point</InputLabel>
    <FormControl variant="outlined" className={classes.FormControl}>
      <Select 
        name="dealerId"
        value={values.dealerId}
        onChange={handleInputChange}
        disabled={!values.zoneId} // 未选Zone时禁用经销商选择框,提升交互体验
      >
        <MenuItem value="">Select Dealer</MenuItem>
        {
          dealerList.map(x => (
            <MenuItem key={x.id} value={x.id}>{x.name}</MenuItem>
          ))
        }
      </Select>
    </FormControl>                
  </form>
);

后端.NET Core接口修改

给Dealer的GET接口新增zoneId参数,根据传入值过滤返回对应经销商即可,示例代码:

[HttpGet]
public IActionResult GetDealers(int? zoneId)
{
    var dealers = _context.Dealers.AsQueryable();
    if(zoneId.HasValue)
    {
        dealers = dealers.Where(d => d.ZoneId == zoneId.Value);
    }
    return Ok(dealers.ToList());
}

内容的提问来源于stack exchange,提问作者S. Arafin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 02:45:03