Mui TextField刷新时值与占位符同时显示的问题求助
问题:MUI TextField在刷新页面时同时显示值和占位符
在表单编辑模式下刷新页面时,MUI TextField组件中会同时显示值和占位符。以下是相关代码:
表单组件
const Form = () => { // fetch hook to get the settings data. const settings = useGetSettingsQuery(); // initialize the useFormik hook with the data just fetched const form = useSettingsForm({ initialValues: settings.data?.data ?? {} }); return ( <Box> <Grid container spacing={2}> <Grid item xs={12}> <TextField fullWidth name={'id'} label={'id'} placeholder={'ticket id'} variant="outlined" value={form.values.id} onChange={form.handleChange} /> </Grid> <Grid item xs={12}> initial values <pre>{JSON.stringify({ id: form.initialValues.id }, null, 2)}</pre> </Grid> <Grid item xs={12}> current value values <pre>{JSON.stringify({ id: form.values.id }, null, 2)}</pre> </Grid> </Grid> </Box> ); };
自定义hook
export const useSettingsForm = ({ initialValues }: Props) => { return useFormik<Partial<ISetting>>({ enableReinitialize: true, initialValues: { ...initialValues, }, validationSchema: Yup.object().shape({}), onSubmit: async (values) => { console.log('submitted -> ', values); }, }); };
RTK Query的apiSlice片段
export const settingApiSlice = apiSlice.injectEndpoints({ endpoints(builder) { return { getSettings: builder.query<IGetSettingsResp, void>({ query() { return `/setting`; }, providesTags: ['setting'], }), }; }, }); export const { useGetSettingsQuery } = settingApiSlice;
原因分析
问题核心是异步数据加载的时序异常:
- 页面刷新后,RTK Query请求先处于
pending状态,此时settings.data为undefined,Formik初始值为空对象,form.values.id是undefined。 - MUI TextField在
value为undefined时,会判定为未受控状态,此时占位符显示,label停留在输入框内部。 - 数据加载完成后,
enableReinitialize触发Formik更新值,但如果返回的id是空字符串,或组件状态同步不及时,就会出现值与占位符同时显示的情况。 - 受控组件的
value需始终为字符串类型,传递undefined会导致组件行为异常。
解决方案
方案1:确保TextField的value始终为字符串
将TextField的value设置为兜底空字符串,避免传递undefined:
<TextField fullWidth name={'id'} label={'id'} placeholder={'ticket id'} variant="outlined" value={form.values.id ?? ''} // 确保值为字符串类型 onChange={form.handleChange} />
方案2:处理异步加载状态,延迟渲染表单
在数据加载完成前显示加载提示,避免渲染未就绪的输入框:
const Form = () => { const settings = useGetSettingsQuery(); // 数据加载中时显示加载状态 if (settings.isLoading) { return <Box>加载中...</Box>; } const form = useSettingsForm({ initialValues: settings.data?.data ?? {} }); return ( // 原表单内容 ); };
方案3:初始化Formik时设置默认空字符串
在自定义hook中给id字段设置默认空字符串,避免初始值为undefined:
export const useSettingsForm = ({ initialValues }: Props) => { return useFormik<Partial<ISetting>>({ enableReinitialize: true, initialValues: { id: '', // 设置默认空字符串 ...initialValues, }, validationSchema: Yup.object().shape({}), onSubmit: async (values) => { console.log('submitted -> ', values); }, }); };
内容的提问来源于stack exchange,提问作者Lazybob
相关产品推荐
相关产品推荐

