Getting the error in browser Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()
My code:
import { yupResolver } from '@hookform/resolvers/yup'
import { useState } from 'react'
import { SubmitHandler, useForm } from 'react-hook-form'
import { contactSchema } from 'schemas/schemas'
import { InputFloatLabel } from './components/Inputs/InputFloatLabel'
type TypeFormInput = {
name: string
email: string
textarea: string
}
export const Register = () => {
const [isLoading, setIsLoading] = useState(false)
const {
register,
handleSubmit,
formState: { errors },
} = useForm<TypeFormInput>({ resolver: yupResolver(contactSchema) })
const onSubmit: SubmitHandler<TypeFormInput> = async ({ name, email }) => {
console.log('🚀 ~ file: Register.tsx ~ line 25 ~ email', email)
console.log('🚀 ~ file: Register.tsx ~ line 25 ~ name', name)
}
return (
<div>
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<InputFloatLabel
type="text"
placeholder="Name"
{...register('name')}
/>
<button type="submit">{isLoading ? 'Loading' : 'Send Mail'}</button>
</div>
</form>
</div>
)
}
And the Input comp:
import { useState } from 'react'
type typeInput = {
placeholder: string
type?: string
}
export const InputFloatLabel: React.FC<typeInput> = ({ type, placeholder, ...props }) => {
const [isActive, setIsActive] = useState(false)
const handleTextChange = (text: string) => {
if (text !== '') setIsActive(true)
else setIsActive(false)
}
return (
<div>
<input
{...props}
id={placeholder}
type={placeholder ? placeholder : 'text'}
onChange={(e) => handleTextChange(e.target.value)}
/>
<label htmlFor={placeholder}>
{placeholder ? placeholder : 'Placeholder'}
</label>
</div>
)
}
I don't have this issue with ChakraUI that I've built but now just doing plain input as a separate component getting that issue.
I have tried some suggestions from here, but still can't fix it: https://github.com/react-hook-form/react-hook-form/issues/85
React see's a ref being passed, but you aren't using a forwardRef component. In addition to this, then you need to actually use the ref (and props) which you don't appear to be doing now in SelectCompanyField that are being provided by Controller
A React form library that is both well thought out and flexible enough to get out of your way when you need it to. After fussing around with React forms for years, switching to react-hook-form feels like a superpower.
Reducing the amount of code you need to write, and removing unnecessary re-renders are some of the primary goals of React Hook Form. Now dive in and explore with the following example:
Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef ()? atomiks/tippyjs-react#49 Warning: Function components cannot be given refs. Attempts to access this ref will fail. diegoddox/react-redux-toastr#220
You forgot to forward the ref in your InputFloatLabel. See https://reactjs.org/docs/forwarding-refs.html
In your case it would look like this:
export const InputFloatLabel: React.FC<typeInput> =
// Use React.forwardRef
React.forwardRef(({type, placeholder, ...props}, ref) => {
const [isActive, setIsActive] = useState(false)
const handleTextChange = (text: string) => {
if (text !== '') setIsActive(true)
else setIsActive(false)
}
return (
<div>
<input
ref={ref /* Pass ref */}
{...props}
id={placeholder}
type={placeholder ? placeholder : 'text'}
onChange={(e) => handleTextChange(e.target.value)}
/>
<label htmlFor={placeholder}>
{placeholder ? placeholder : 'Placeholder'}
</label>
</div>
)
})
So the issue is that I think that the {...register("name"}}
line actually includes a ref property. You could console.log that out to verify; this is what I found to be true when using {...field}
with the ControlledComponent. A very quick fix to get rid of the console error is to just, after the line with the spread, to add a ref={null}
to override this ref that is being passed in from the library.
In https://react-hook-form.com/faqs, scroll to "How to share ref usage?" may help?
import React, { useRef } from "react";
import { useForm } from "react-hook-form";
export default function App() {
const { register, handleSubmit } = useForm();
const firstNameRef = useRef(null);
const onSubmit = data => console.log(data);
const { ref, ...rest } = register('firstName');
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...rest} name="firstName" ref={(e) => {
ref(e)
firstNameRef.current = e // you can still assign to ref
}} />
<button>Submit</button>
</form>
);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With