React中修改state对象属性后useEffect未触发重渲染求助
问题根源
你的useEffect未触发的核心原因是:Formik管理的表单字段与你自定义的category useState完全独立。选择框变更时仅更新了Formik内部的表单状态,并未修改category.categoryId的值,导致useEffect的依赖项没有变化,因此不会执行。
解决方案
根据你的使用场景,提供两种可行的修改方案:
方案1:继续使用Formik管理表单状态
既然已经用Formik处理表单,无需额外维护category useState,直接基于Formik的状态触发useEffect:
父组件修改
import { useFormik } from 'formik'; // 移除原有的category useState,改用Formik管理初始值 const formik = useFormik({ initialValues: { categoryId: "", // 其他需要的表单字段可以在这里补充 }, onSubmit: (values) => { // 表单提交逻辑 }, }); // 修改useEffect 2,依赖Formik的categoryId值 useEffect(() => { console.log("Use effect 2"); console.log(`ID: ${formik.values.categoryId}`); // 在这里调用API获取选中项的更多数据 }, [formik.values.categoryId]); // 选择框组件调用保持不变 <SelectInput name='categoryId' placeholder='Category' label='Category' options={categories} search />
方案2:自定义管理category状态(脱离Formik字段管理)
如果希望完全自己控制category状态,需要改造SelectInput为受控组件:
1. 改造SelectInput组件
import { DropdownItemProps, Form, Label, Select } from "semantic-ui-react"; interface Props { placeholder: string; name: string; label?: string; options: DropdownItemProps[]; search: boolean; value: string | null; onChange: (value: string) => void; touched?: boolean; error?: string; } export default function SelectInput(props: Props) { return ( <Form.Field error={props.touched && !!props.error}> <label>{props.label}</label> <Select clearable options={props.options} value={props.value || null} onChange={(event, data) => props.onChange(data.value as string)} placeholder={props.placeholder} search={props.search} /> {props.touched && props.error ? ( <Label basic color='red'> {props.error} </Label> ) : null} </Form.Field> ); }
2. 父组件修改
// 保留category useState,补充setCategory方法 const [category, setCategory] = useState<CategoryInstance>({ id: "", number: 1, sponsor: "", logo: "", permit: "", bumpSpot: 128, raceEventId: "670d34d5-134b-4408-91bd-691f8c4b62d2", categoryId: "", configurationId: "", category: null, configuration: null, raceEvent: null, ladder: null, entryList: [], rounds: [], }); // 原useEffect 2无需修改,现在会正确触发 useEffect(() => { console.log("Use effect 2"); console.log(`ID: ${category.categoryId}`); // 调用API获取更多数据 }, [category.categoryId]); // 选择框组件改为受控模式 <SelectInput name='categoryId' placeholder='Category' label='Category' options={categories} search value={category.categoryId} onChange={(value) => setCategory(prev => ({...prev, categoryId: value}))} />
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

