jaredpalmer / formik

Build forms in React, without the tears 😭
https://formik.org
Apache License 2.0
33.98k stars 2.79k forks source link

External ref doesn't work on v2.0.8 #2155

Closed DalerAsrorov closed 4 years ago

DalerAsrorov commented 4 years ago

🐛 Bug report

The form ref doesn't work on the version v2.0.8. The example code that Jeff posted here: https://codesandbox.io/s/formik-codesandbox-template-o7imu

In version v1.2.0 it works fine without errors but in the latest version it throws an error for submitForm:

Uncaught TypeError: Cannot read property 'submitForm' of null

Current Behavior

Throws an error and doesn't retrieve the values of the form on submit.

Expected behavior

Should not throw an error and pass on the form values to the callback on submit.

Reproducible example

Make sure the formik dependency is on the lates tversion: https://codesandbox.io/s/formik-codesandbox-template-o7imu

https://codesandbox.io/s/formik-codesandbox-template-o7imu

Suggested solution(s)

Additional context

Your environment

Software Version(s)
Formik 2.0.8
React 16.8.0
TypeScript N/A
Browser Chrome
npm/Yarn yarn (and codesandbox)
Operating System Mac OS
crobinson42 commented 4 years ago

I verified this is still an issue in formik@2.1.0

drivasperez commented 4 years ago

I think this is a duplicate of #1603. If you look in the console in your sandbox, you'll see this warning message:

Warning: Function components cannot be given refs. 
Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

Check the render method of `App`.
    in Formik (created by App)
    in div (created by App)
    in App

This workflow just isn't possible in v2 at the moment. There are moves being made in #1972 to restore the functionality.

DalerAsrorov commented 4 years ago

Thanks @drivasperez this PR may actually solve the problem. It's just annoying that an app can break due to stuff like this. Hope it gets fixed ASAP. This is particularly helpful if you want a simple way to submit your form using the button outside of the form context.

drivasperez commented 4 years ago

It's a bit strange to look at, but you can get the same functionality by making a small component that grabs the formik context, then exposes it to a ref with useImperativeHandle. It's worked okay for me at work.

const FormController = React.forwardRef(function(_props, ref) {
  const formik = useFormikContext();
  React.useImperativeHandle(ref, () => ({ ...formik }), [formik]);
  return null;
});

You place this in your Formik and pass it the ref. CodeSandbox here: https://codesandbox.io/s/dreamy-mendeleev-95fj7

DalerAsrorov commented 4 years ago

Thanks @drivasperez I will try that. I am sure it will work. I am not very familiar with useImperativeHandler but I will take a look now. I still hope that in the future we can do a regular ref.

fbricenho commented 4 years ago

This issue exists on 2.1.1 (I personally checked) and still on 2.1.2 according to release notes. I'll use the workaround with useImperativeHandle tho I hope we get back the old functionality 😄

jaredpalmer commented 4 years ago

@fbricenho It works in 2.1.2. You can now do <Formik innerRef={ref} /> See: https://codesandbox.io/s/ancient-rain-gl0hw

Now wondering though if we should have used forwardRef though? I think that would make a lot more sense. Right?