react-final-form
react-final-form copied to clipboard
forwardRef
Bug report
It seems I can't set a ref anymore on <Form /> components.
I looked into <ReactFinalForm /> component and it doesn't seem to forward the ref.
Maybe using useImperativeHandle to expose the form api would be a solution?
<Form> doesn't, itself, render any components, so I'm not sure what the ref would be too...?
Would be nice to access the form api through a ref.
Seems like you could do a formRef.current = form in your <Form>'s render prop (or a <FormSpy>)... Not gonna be set on first render, but would be from there on. 🤔
It looks a bit hackish and limiting. Besides that, what if I don't have access to Form's children? I can probably submit a PR myself toward the end of the week and maybe present some actual use cases if you're ok with that.
How about something like this:
const MyForm = () => {
const form = React.useRef()
return (
<Form onSubmit={onSubmit} formRef={form}>
...
</Form>
}
Where the form element will be courteous enough to pass you back the form instance. About what you're looking for?
That's exactly what I was looking for. Except that I think it's enough to use the ref property and not have a custom formRef property for that.
This can probably be achieved with something like this (in ReactFinalForm.js):
const ReactFinalForm = forwardRef(({...}, ref) => {
const form: FormApi = useConstant(() => {
const f = createForm(config)
f.pauseValidation()
return f
})
React.useImperativeHandle(ref, () => form);
});
I have dozens of components that use this:
<Form
....
ref={el => (this.form = el)}
/>
And since upgrading to v6 of react-final-form I'm getting this Warning everywhere:
Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
FYI - this is a breaking change that needs to be fixed in a patch version ASAP.
In v5 this works:
<Form
onSubmit={() => this.form.form.reset()}
ref={el => (this.form = el)}
/>
and no longer works in v6 due to the ref not being forwarded by react-final-form
Any status on this? I can add a PR for forwardRef if help is wanted
@ChrisWiles yes please do, help is required here https://github.com/final-form/react-final-form/pull/608#issuecomment-525540956 but someone with flow experience needs to get into it.
Please add forwardRef to react-final-form it's a must have.
For react-native, it gives the worst user experience without it as we can't jump from a field to another using the NEXT button, see https://github.com/final-form/react-final-form/issues/779
Hi guys, that's a big issue here, is there any chance that someone with flow experience solves #608 ?
Without flow experience, how can we help this to move forward?
v6.5.0 as been released with the merge : thanks for the release ! I would like to know if anyone have tested it ? Passing const ref = useRef(); to the <Field ref={ref} /> does not save the ref as I expect.
I also tried createRef(), both did return a current with value undefined.
I think this would be great. Having let in your component or manually mutating ref.current feels wrong and always raises eyebrows in our code reviews when someone needs the FormApi outside the component (i.e. an external submit button which we have in TONS of places in our React Native app such as on the menu bar).
@viczam 's solution seems the most correct, React way to do this:
const ReactFinalForm = forwardRef(({...}, ref) => {
const form: FormApi = useConstant(() => {
const f = createForm(config)
f.pauseValidation()
return f
})
React.useImperativeHandle(ref, () => form);
});
This would also make usage more inline with the ref on Field as well!
Are there strong arguments against just doing it this way?
How is this issue still open? It seems wild that in 2023 you still can't:
const formRef = useRef();
return (
<Form ref={formRef} ...>
{...}
</Form>
);
And get a ref to the form object. We've had to introduce a silly wrapper component to achieve what seems like a very simple bit of functionality that should be restored to the core library.