Formik选择文件时表单重复渲染问题求助
解决Formik文件上传时表单重复渲染问题
一、修复setFieldValue的使用问题
你的代码中未从Formik实例解构setFieldValue,若调用的是外部方法可能引发异常。先确保正确解构:
const { values, handleBlur, handleChange, touched, handleSubmit, errors, setFieldValue } = useFormik({ initialValues: { userName: userName, name: name, lastName: lastName, password: password, ownerId: ownerid, url: url ? url : "", }, validationSchema: AgentSchema, onSubmit: onSubmit, });
二、稳定initialValues避免Formik重复初始化
如果userName、name等是父组件传入的props,每次父组件更新会生成新的initialValues对象,导致Formik重新初始化触发重渲染。用useMemo缓存初始值:
const initialValues = useMemo(() => ({ userName: userName, name: name, lastName: lastName, password: password, ownerId: ownerid, url: url ? url : "", }), [userName, name, lastName, password, ownerid, url]); const { values, handleBlur, handleChange, touched, handleSubmit, errors, setFieldValue } = useFormik({ initialValues, validationSchema: AgentSchema, onSubmit: onSubmit, });
三、用React.memo优化组件防止不必要重渲染
将表单组件用React.memo包裹,仅在props变化时才重渲染:
const AgentForm = React.memo(({ userName, name, lastName, password, ownerid, url, onSubmit }) => { // 此处编写Formik初始化及表单元素代码 });
四、用useRef存储文件,提交时再同步到Formik(避免实时更新Formik状态)
若不想因文件选择触发Formik状态更新导致重渲染,可通过useRef存储文件,在提交阶段统一处理:
const fileRef = useRef(null); // 自定义提交逻辑,整合文件与表单数据 const handleSubmitWithFile = (values) => { const formData = new FormData(); // 写入普通表单字段 Object.keys(values).forEach(key => formData.append(key, values[key])); // 写入文件 if (fileRef.current?.files[0]) { formData.append('url', fileRef.current.files[0]); } // 调用原提交方法 onSubmit(formData); }; // Formik配置中替换提交方法 const { values, handleBlur, handleChange, touched, handleSubmit, errors } = useFormik({ initialValues: { /* 初始值配置 */ }, validationSchema: AgentSchema, onSubmit: handleSubmitWithFile, }); // 文件输入框绑定ref,无需关联Formik状态 <input type='file' accept='image/*' ref={fileRef} />
内容的提问来源于stack exchange,提问作者Ramazan Aktaş
相关产品推荐
相关产品推荐

