Formik结合MaterialUI TextField的值更新及重渲染问题
问题1:TextField不显示Formik初始值
你的TextField没有绑定Formik管理的values字段,Formik要求表单组件是受控组件才能同步状态。给TextField添加value={values.toEmail01}即可:
<TextField id="toEmail01" name="toEmail01" value={values.toEmail01} // 绑定Formik维护的状态值 onChange={handleChange} onBlur={handleBlur} helperText={touched.toEmail01 ? errors.toEmail01 : ""} error={touched.toEmail01 && Boolean(errors.toEmail01)} margin="dense" variant="standard" fullWidth />
之前依赖defaultValue是把TextField当成非受控组件,和Formik的受控模式冲突,必须绑定value到Formik的values,才能正常显示初始值并保持状态同步。
问题2:Canvas更新导致组件重渲染,TextField值被刷新
核心原因
组件重渲染时,你当前的initialValues是在组件内部直接声明的对象,每次重渲染都会生成新的引用,Formik可能误判为初始值变更;同时Canvas状态更新触发整个父组件重渲染,导致表单组件不必要的刷新。
解决步骤
- 稳定initialValues引用:用
useMemo包裹initialValues,避免每次重渲染创建新对象:import { useMemo } from 'react'; const initialValues = useMemo(() => ({ toEmail01: "<user>@xyz.co", }), []); // 空依赖数组确保只初始化一次 - 拆分Canvas独立组件:把Canvas相关逻辑抽成单独组件,用
React.memo包裹,仅当Canvas的props变化时才重渲染:
在父组件中传递Canvas所需的状态作为props,这样父组件重渲染时,只要Canvas的props不变,CanvasComponent就不会重新渲染,避免波及表单组件。import { memo } from 'react'; const CanvasComponent = memo(({ canvasText }) => { // 这里写Canvas的渲染和更新逻辑 return <canvas>...</canvas>; }); - 关闭enableReinitialize:这个属性仅用于动态更新initialValues的场景,你的情况不需要开启,保持默认
false即可,防止Formik意外重置表单状态。
内容的提问来源于stack exchange,提问作者Dev
相关产品推荐
相关产品推荐

