Formik初始值无法从API调用中填充问题求助
问题描述
通过URL参数中的ID从后端获取产品数据,控制台确认数据(包括product.title等字段)已成功返回,但使用Formik编辑产品时,输入框无法填充初始值,打印formik.initialValues显示product.title为undefined。
相关代码
获取数据的useEffect代码
useEffect(() => { const fetchProductById = async () => { try { const response = await axios.get(`http://localhost:3005/product/${prodId}`) setProduct(response.data) } catch (err) { console.error(err) } } fetchProductById(); },[prodId]);
Formik初始值配置
const editProductFormik = useFormik({ initialValues: { title: product.title, description: '', price: '', images: images, coverImage: coverImage, location: '', age: '', condition: '', Category: '', SubCategory : '', seller : seller, }, // 省略validationSchema、onSubmit等其他配置 })
产品标题输入框代码
<Box> <Input mr={2} width="250px" type="title" value={editProductFormik.values.title} onChange={editProductFormik.handleChange("title")} marginBottom="10px" /> {editProductFormik.touched.title && editProductFormik.errors.title ? ( <Text mt={2} color="red" fontWeight="bold">{editProductFormik.errors.title}</Text> ) : null} </Box>
问题原因
Formik的initialValues在组件首次渲染时就会被初始化,而此时product的初始值是undefined(或空对象),所以product.title自然为undefined。后续useEffect异步获取到数据并更新product后,Formik不会自动重新初始化initialValues,导致输入框无法拿到正确的初始值。
解决方案
提供三种可行的解决方法,按需选择:
方法1:延迟初始化Formik,等待数据加载完成
在product未加载完成时,先渲染加载状态,等数据到位后再初始化Formik:
// 假设product初始值为null/undefined if (!product) { return <div>加载中...</div> } const editProductFormik = useFormik({ initialValues: { title: product.title, description: product.description || '', price: product.price || '', images: images, coverImage: coverImage, location: product.location || '', age: product.age || '', condition: product.condition || '', Category: product.Category || '', SubCategory : product.SubCategory || '', seller : seller, }, // 其他配置 })
方法2:用Formik的setValues手动更新表单
保留Formik初始值为空,在数据获取成功后调用setValues更新表单:
const editProductFormik = useFormik({ initialValues: { title: '', description: '', price: '', images: images, coverImage: coverImage, location: '', age: '', condition: '', Category: '', SubCategory : '', seller : seller, }, // 其他配置 }) useEffect(() => { const fetchProductById = async () => { try { const response = await axios.get(`http://localhost:3005/product/${prodId}`) setProduct(response.data) // 数据获取后更新表单值 editProductFormik.setValues({ title: response.data.title, description: response.data.description || '', price: response.data.price || '', location: response.data.location || '', age: response.data.age || '', condition: response.data.condition || '', Category: response.data.Category || '', SubCategory : response.data.SubCategory || '', images: images, coverImage: coverImage, seller: seller, }) } catch (err) { console.error(err) } } fetchProductById(); },[prodId, editProductFormik.setValues]) // 需添加setValues到依赖数组
方法3:启用Formik的enableReinitialize属性(推荐)
Formik v2及以上版本支持enableReinitialize配置,开启后当initialValues依赖的product变化时,会自动重新初始化表单:
const editProductFormik = useFormik({ initialValues: { title: product?.title || '', // 用可选链避免product未加载时报错 description: product?.description || '', price: product?.price || '', images: images, coverImage: coverImage, location: product?.location || '', age: product?.age || '', condition: product?.condition || '', Category: product?.Category || '', SubCategory : product?.SubCategory || '', seller : seller, }, enableReinitialize: true, // 关键配置 // 其他配置 })
内容的提问来源于stack exchange,提问作者novicecoder
相关产品推荐
相关产品推荐

