ForwardRef 警告 React-hook-forms with Material UI TextField
Posted
技术标签:
【中文标题】ForwardRef 警告 React-hook-forms with Material UI TextField【英文标题】:ForwardRef warning React-hook-forms with Material UI TextField 【发布时间】:2021-02-23 10:54:39 【问题描述】:我正在尝试使用带有 Material UI 输入的 react-hook-forms 构建一个表单(在这种情况下,我是 TextField 的自定义变体)。尽管表单似乎工作得很好,但在呈现表单时会在控制台中触发警告消息。
警告:函数组件不能被赋予 refs。尝试去 访问此 ref 将失败。你的意思是使用 React.forwardRef() 吗?
我正在使用 react-hook-form 的控制器来包装我的 TextField(按照文档的建议)
非常欢迎任何建议或解决方案!
在 TextField 组件和出现此问题的表单下方:
组件文本字段
const TextField = props =>
const
icon,
disabled,
errors,
helperText,
id,
label,
value,
name,
required,
...rest
= props;
const classes = useFieldStyles();
return (
<MuiTextField
...rest
name=name
label=label
value=value || ''
required=required
disabled=disabled
helperText=helperText
error=errors
variant="outlined"
margin="normal"
color="primary"
InputProps=
startAdornment: icon,
classes:
notchedOutline: classes.outline,
,
InputLabelProps=
className: classes.inputLabel,
/>
)
;
TextField.propTypes =
icon: PropTypes.node,
disabled: PropTypes.bool,
label: PropTypes.string,
id: PropTypes.string,
value: PropTypes.any,
required: PropTypes.bool,
helperText: PropTypes.string,
;
export default TextField;
组件登录表单
const LoginForm = () =>
const handleSubmit, errors, control = useForm();
const onSubmit = values => console.log(values);
return (
<form onSubmit=handleSubmit(onSubmit)>
<Typography variant="h5" color="primary" gutterBottom>
Login
</Typography>
<Box py=3 display="flex" flexDirection="column">
<Controller
as=TextField
label="Username"
name="username"
control=control
errors=errors
required
/>
<Controller
as=TextField
label="Password"
type="password"
name="password"
control=control
errors=errors
required
/>
<Link>
Forgot your password?
</Link>
</Box>
<Button variant="contained" color="primary" fullWidth type="submit">
Submit
</Button>
</form>
)
;
【问题讨论】:
【参考方案1】:尝试使用Controller
的render prop而不是as
,因为TextField的暴露引用实际上称为inputRef,而Controller
试图访问ref
。
import React, useState from "react";
import ReactDOM from "react-dom";
import useForm, Controller from "react-hook-form";
import Header from "./Header";
import TextField, ThemeProvider, createMuiTheme from "@material-ui/core";
import "react-datepicker/dist/react-datepicker.css";
import "./styles.css";
import ButtonsResult from "./ButtonsResult";
let renderCount = 0;
const theme = createMuiTheme(
palette:
type: "dark"
);
const defaultValues =
TextField: "",
TextField1: ""
;
function App()
const handleSubmit, reset, control = useForm( defaultValues );
const [data, setData] = useState(null);
renderCount++;
return (
<ThemeProvider theme=theme>
<form onSubmit=handleSubmit((data) => setData(data)) className="form">
<Header renderCount=renderCount />
<section>
<label>MUI TextField</label>
<Controller
render=(props) => (
<TextField
value=props.value
onChange=props.onChange
inputRef=props.ref
/>
)
name="TextField"
control=control
rules= required: true
/>
</section>
<section>
<label>MUI TextField</label>
<Controller
render=(props) => (
<TextField
value=props.value
onChange=props.onChange
inputRef=props.ref
/>
)
name="TextField1"
control=control
rules= required: true
/>
</section>
<ButtonsResult ... data, reset, defaultValues />
</form>
</ThemeProvider>
);
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
您可以点击以下链接查看实际行为,现在通过控制器正确分配 ref,我们可以在出现错误时成功聚焦该字段以获得更好的可访问性。
https://codesandbox.io/s/react-hook-form-focus-74ecu
【讨论】:
谢谢比尔,我后来也采用了这种方法,这确实可以防止 Ref.我还发现以前版本的 react-hook-form (v 6.0.8) 在使用 'as' 道具时没有这种行为 是的,没错。我们在 6.10.0 中引入了额外的ref
属性以改进焦点管理。 github.com/react-hook-form/react-hook-form/blob/master/…【参考方案2】:
警告完全正确,正如官方文档所建议的那样,它认为您没有触及功能组件部分。 Link to the offical docs
您不能将 ref 赋予功能组件,因为它们没有实例
如果你想让人们对你的函数组件进行引用,你可以使用forwardRef
(可能与useImperativeHandle
一起使用),或者你可以将组件转换为一个类。
但是,只要您像这样引用 DOM 元素或类组件,您就可以在函数组件中使用 ref
属性:
function CustomTextInput(props)
// textInput must be declared here so the ref can refer to it
const textInput = useRef(null);
function handleClick()
textInput.current.focus();
return (
<div>
<input
type="text"
ref=textInput />
<input
type="button"
value="Focus the text input"
onClick=handleClick
/>
</div>
);
【讨论】:
以上是关于ForwardRef 警告 React-hook-forms with Material UI TextField的主要内容,如果未能解决你的问题,请参考以下文章
React:警告:不能给函数组件提供参考。尝试访问此 ref 将失败。你的意思是使用 React.forwardRef() 吗?
ForwardRef 警告 React-hook-forms with Material UI TextField