基于选中名称筛选用户的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
相关产品推荐
相关产品推荐

