Material UI与React Hook Form集成问题:无法取值且页面不渲染
React Hook Form 集成 Material UI TextField 渲染失败及提交问题
使用版本:MUI 5.10.4、React Hook Form 7.36.1
集成过程中遇到页面无法渲染的问题,尝试通过onSubmit捕获输入值并打印到控制台也未成功。在TextField中添加inputRef={register}后,出现以下错误:
控制台错误信息
Uncaught TypeError: path.split is not a function at get (get.ts:11:1) at register (createFormControl.ts:923:1) at setRef (setRef.js:16:1) at useForkRef.js:15:1 at setRef (setRef.js:16:1) at useForkRef.js:16:1 at commitAttachRef (react-dom.development.js:20875:1) at commitLayoutEffects (react-dom.development.js:23431:1) at HTMLUnknownElement.callCallback (react-dom.development.js:3945:1) at Object.invokeGuardedCallbackDev (react-dom.development.js:3994:1) get @ get.ts:11 register @ createFormControl.ts:923 setRef @ setRef.js:16 (anonymous) @ useForkRef.js:15 setRef @ setRef.js:16 (anonymous) @ useForkRef.js:16 commitAttachRef @ react-dom.development.js:20875 commitLayoutEffects @ react-dom.development.js:23431 callCallback @ react-dom.development.js:3945 Consider adding an error boundary to your tree to customize error handling behavior. Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries. logCapturedError @ react-dom.development.js:20085 update.callback @ react-dom.development.js:20118 callCallback @ react-dom.development.js:12318 commitUpdateQueue @ react-dom.development.js:12339 commitLifeCycles @ react-dom.development.js:20736 commitLayoutEffects @ react-dom.development.js:23426 callCallback @ react-dom.development.js:3945 invokeGuardedCallbackDev @ react-dom.development.js:3994
原始代码
import { Button, Grid, Typography } from '@mui/material'; import TextField from '@mui/material/TextField' import { useForm, Controller } from 'react-hook-form'; const CreateOrUpdateJob = () => { const {register, handleSubmit, control, reset} = useForm(); const onSubmit = (data: any) => console.log(data); return ( <> <Typography variant="h2" color="initial" sx={{ marginTop: '1rem', marginBottom: '1rem', textAlign: 'center', fontSize: '1.5rem', color: '#000000', fontWeight: '700' }} > Adicionar Vaga </Typography> <Grid container spacing={0} direction="column" alignItems="center" justifyContent="center" sx={{ minHeight: '100vh', gap: '1rem' // background opacity 0.5 }} > <form action="" style={{ display: 'grid', gap: '1rem', width: '100%', maxWidth: '1440px', padding: '0 1rem', margin: '0 auto' }} > <Controller name="jobName" defaultValue="" control={control} render={({ field:{onChange, value}}) => ( <TextField label="Name Job" id="jobName" name="jobName" value={value} onChange={onChange} variant="outlined" fullWidth inputRef={register} /> )} /> <Button variant="contained" color="success" size="large" type="submit" fullWidth onSubmit={handleSubmit(onSubmit)} > Criar vaga </Button> <Button variant="contained" color="success" size="large" type="submit" fullWidth onClick={() => { reset(); }} > Reset </Button> </form> </Grid> </> ); }; export default CreateOrUpdateJob
问题原因及解决方案
1. Controller 与 register 冲突
使用Controller组件时,无需再给TextField添加inputRef={register}。Controller已经通过control属性接管了表单控件的状态管理,直接传入register函数会导致内部逻辑冲突,触发path.split is not a function错误。
2. 提交事件绑定错误
表单的提交事件应该绑定在<form>标签上,而非<Button>组件。Button没有onSubmit属性,将handleSubmit(onSubmit)绑定到form的onSubmit属性即可正确触发提交逻辑。
3. Reset按钮类型错误
Reset按钮的type应该设为button,而非submit。否则点击Reset按钮会触发表单提交,而非执行重置操作。
修正后的代码
import { Button, Grid, Typography } from '@mui/material'; import TextField from '@mui/material/TextField' import { useForm, Controller } from 'react-hook-form'; const CreateOrUpdateJob = () => { const { handleSubmit, control, reset } = useForm(); const onSubmit = (data: any) => console.log(data); return ( <> <Typography variant="h2" color="initial" sx={{ marginTop: '1rem', marginBottom: '1rem', textAlign: 'center', fontSize: '1.5rem', color: '#000000', fontWeight: '700' }} > Adicionar Vaga </Typography> <Grid container spacing={0} direction="column" alignItems="center" justifyContent="center" sx={{ minHeight: '100vh', gap: '1rem' }} > <form action="" style={{ display: 'grid', gap: '1rem', width: '100%', maxWidth: '1440px', padding: '0 1rem', margin: '0 auto' }} onSubmit={handleSubmit(onSubmit)} > <Controller name="jobName" defaultValue="" control={control} render={({ field:{onChange, value}}) => ( <TextField label="Name Job" id="jobName" name="jobName" value={value} onChange={onChange} variant="outlined" fullWidth /> )} /> <Button variant="contained" color="success" size="large" type="submit" fullWidth> Criar vaga </Button> <Button variant="contained" color="success" size="large" type="button" fullWidth onClick={() => reset()} > Reset </Button> </form> </Grid> </> ); }; export default CreateOrUpdateJob
内容的提问来源于stack exchange,提问作者Zan
相关产品推荐
相关产品推荐

