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

基于选中名称筛选用户的React Formik组件功能异常排查

解决Formik表单中根据选中名称筛选对应用户列表的问题

问题核心:在React项目中使用Formik构建表单,选中「Select Name」下拉框的选项后,「username」下拉框需要仅展示对应名称下的用户列表,但当前逻辑会把选中项的所有字段值都显示出来,需修正handleChange函数实现正确筛选。

问题分析

原代码中handleChange函数使用Object.values(name)遍历选中项的所有属性值,然后全部添加到选项列表中,导致非用户字段(如selectName)也被当作选项展示。正确逻辑应该是仅提取选中项中user字段对应的用户数组,再转换成下拉框需要的格式。

修正后的handleChange函数

const handleChange = (e) => {
  const selectedName = e.target.value;
  // 找到选中的名称对应的数据项
  const selectedItem = nameList.find((data) => data.selectName === selectedName);
  
  // 处理未找到匹配项的情况,避免报错
  if (!selectedItem) {
    AssignSearchesForm.setFieldValue("selectName", selectedName);
    AssignSearchesForm.setFieldValue("username", []);
    return;
  }

  // 仅提取user字段的数组,转换为下拉框需要的{value, label}格式
  const newOptions = selectedItem.user.map(user => ({
    value: user,
    label: user
  }));

  AssignSearchesForm.setFieldValue("selectName", selectedName);
  AssignSearchesForm.setFieldValue("username", newOptions);
};

完整修正后的代码片段

export default function App() {
  const AssignSearchesForm = useFormik({
    initialValues: {
      selectName: "",
      username: []
    },
    onSubmit: (values) => {
      console.log(values);
    }
  });

  const handleChange = (e) => {
    const selectedName = e.target.value;
    const selectedItem = nameList.find((data) => data.selectName === selectedName);
    
    if (!selectedItem) {
      AssignSearchesForm.setFieldValue("selectName", selectedName);
      AssignSearchesForm.setFieldValue("username", []);
      return;
    }

    const newOptions = selectedItem.user.map(user => ({
      value: user,
      label: user
    }));

    AssignSearchesForm.setFieldValue("selectName", selectedName);
    AssignSearchesForm.setFieldValue("username", newOptions);
  };

  console.log(AssignSearchesForm?.values?.username);
  return (
    <div className="App">
      <Card color="primary" variant="outlined">
        <Grid
          sx={{
            mt: 1
          }}
          container
          direction="row"
          spacing={3}
        >
          <Grid item xs={4}>
            <TextField
              sx={{ minWidth: 170 }}
              select
              id="outlined-basic"
              label="Select Name"
              name="selectName"
              size="small"
              onChange={handleChange}
              value={AssignSearchesForm.values.selectName}
            >
              {nameList?.map((option) => (
                <MenuItem key={option.selectName} value={option.selectName}>
                  {option.selectName}
                </MenuItem>
              ))}
            </TextField>
          </Grid>
          <Grid item xs={4}>
            <TextField
              sx={{ minWidth: 170 }}
              select
              id="outlined-basic"
              label="username"
              name="username"
              size="small"
              {...AssignSearchesForm.getFieldProps("username")}
            >
              {AssignSearchesForm?.values?.username.length ? (
                AssignSearchesForm?.values?.username?.map((option) => (
                  <MenuItem key={option.value} value={option.value}>
                    {option.value}
                  </MenuItem>
                ))
              ) : (
                <MenuItem disabled>Please first select name</MenuItem>
              )}
            </TextField>
          </Grid>
          <Grid item xs={4}>
            <Button
              onClick={() => {
                AssignSearchesForm.handleSubmit();
              }}
              variant="contained"
            >
              Add
            </Button>
          </Grid>
        </Grid>
      </Card>
    </div>
  );
}

关键说明

  • 新增了对selectedItem的空值判断,避免因找不到匹配项导致的Cannot read properties of undefined错误
  • 直接使用selectedItem.user.map()转换用户数组,确保仅处理用户列表数据
  • 保持Formik字段更新的逻辑不变,确保表单状态同步

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 12:21:30