Antd v4 Form更新记录时功能异常,setFieldsValue调用效果不符问题求助
问题原因分析
form.setFieldsValue放在useEffect外报警告的原因
组件首次渲染时,DOM 中的 Form 组件还未完成挂载,你创建的 form 实例还没有和 Form 组件绑定,这时候直接调用setFieldsValue就会触发「form 实例未连接到任何 Form 元素」的警告。而且这段代码会在组件每次重渲染时都执行,存在不必要的性能消耗。你后续能正常赋值是因为接口请求完成后singlePost更新触发组件重渲染,此时Form已经挂载完成,所以赋值能生效,但首次渲染的警告无法避免。form.setFieldsValue放在请求useEffect里无法赋值的原因dispatch(getPost(uuid))触发的是异步接口请求,dispatch 调用结束后不会等待接口返回,直接执行后续的setFieldsValue时,store 里的singlePost还是请求前的初始值,自然无法给表单填充正确数据。
解决方案
新增一个 useEffect 监听 singlePost 的变化,等接口返回数据、singlePost 更新后再执行表单赋值操作即可,同时要加非空判断避免无数据时调用方法:
export const PostUpdate = () => { const dispatch = useDispatch(); const { uuid } = useParams(); const [form] = Form.useForm(); const { singlePost } = useSelector( (state) => state.post ); useEffect(() => { dispatch(getPost(uuid)); }, [dispatch, uuid]); // 新增这段useEffect监听数据变化赋值 useEffect(() => { // 确保拿到数据后再赋值 if (singlePost) { form.setFieldsValue({ title: singlePost.title }) } }, [form, singlePost]) return ( <Fragment> <div className="site-layout-background" style={{ padding: 20, minHeight: "70vh" }} > <Title level={5}>Update Post : {singlePost?.title || ''}</Title> <Form layout="vertical" form={form} > <Item name="title" label="Title" rules={[ { required: true, message: "Please enter title of post", }, ]} > <Input /> </Item> <Item> <Button htmlType="submit" type="primary"> Submit </Button> </Item> </Form> </div> </Fragment> ); };
补充说明
如果你的表单初始值不需要后续响应数据变化,也可以直接给 Form 组件传 initialValues 属性,但要注意这个属性只在 Form 组件首次挂载时生效一次,如果初始时 singlePost 为空,后续接口返回数据也不会自动更新表单值,所以异步场景下优先用上述监听 singlePost 的方案。
内容的提问来源于stack exchange,提问作者Nanda

