Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use React.forwardRef in <Formik> #2208

Open
jaredpalmer opened this issue Jan 14, 2020 · 14 comments
Open

Use React.forwardRef in <Formik> #2208

jaredpalmer opened this issue Jan 14, 2020 · 14 comments

Comments

@jaredpalmer
Copy link
Owner

jaredpalmer commented Jan 14, 2020

As of 2.1.2, <Formik> now allows for an innerRef prop. However, we should instead use React.forwardRef + React.useImperativeHandle. This is more intuitive and closer to best practices. The problem though, is that <Formik> takes TypeScript generics for Values and I'm not sure how to express this in with forwardRef. AFAICT, you can't because forwardRef returns a constant and constants can't have generics.

Help?!?!

@drivasperez
Copy link
Contributor

drivasperez commented Jan 14, 2020

How about:

export const Formik = React.forwardRef(function Formik<
  Values extends FormikValues = FormikValues,
  ExtraProps = {}
>(props: FormikConfig<Values> & ExtraProps, ref: any) {
  const formikbag = useFormik<Values>(props);
  const { component, children, render, innerRef } = props;

  // This allows folks to pass a ref to <Formik />
  React.useImperativeHandle(innerRef, () => formikbag);
  React.useImperativeHandle(ref, () => formikbag);
  ...

This seems to infer okay, but I might be misunderstanding.

@jaredpalmer
Copy link
Owner Author

Submit a PR?

@drivasperez
Copy link
Contributor

Done!

@drivasperez
Copy link
Contributor

Ah, never mind, I see the issue.

@johnrom
Copy link
Collaborator

johnrom commented Jan 17, 2020

Doing a little cheating makes this possible. I didn't test too thoroughly, but it seems to work. The main issue is that I had to override the type inference (with as) and so this particular assignment will now be vulnerable to incorrect typings in the future.

#2222

Some external issues related to forwardRef woes:
DefinitelyTyped/DefinitelyTyped#35834
https://stackoverflow.com/a/51898192

And finally, the rabbit hole, where someone attempts to define a way to let TS infer an open generic, and the TS team says "maybe one day": microsoft/TypeScript#24626

@drivasperez
Copy link
Contributor

drivasperez commented Jan 20, 2020

I couldn’t find anything that worked before that doesn’t now. I guess the main concern is: going forward, how can you break it going forward in a way that the “as [...component...]” cast won’t complain about, and is that likely to happen?

@johnrom
Copy link
Collaborator

johnrom commented Jan 21, 2020

Basically, a Formik contributor could change the types incorrectly. I wish we could ignore a specific rule so we wouldn't have to use as and we could protect against all the other errors, but for now as is the best protection we can get. as won't protect against most things, but it'll at least make sure it's kind of the same signature. I made a similar comment here: microsoft/TypeScript#30215

@ProteanCode
Copy link

It touches #2290

@tony
Copy link

tony commented May 4, 2020

A related StackOverflow I thought would be helpful to consider: https://stackoverflow.com/questions/58469229/react-with-typescript-generics-while-using-react-forwardref (answer with some approaches)

@stale stale bot removed the stale label May 4, 2020
@stclairdaniel
Copy link

Any updates on this issue? It's preventing my team from upgrading to Formik 2.x

@julioxavierr
Copy link

+1

@arvigeus
Copy link

What about:

const MyComponent = React.forwardRef(function<T>(props: PropsType<T>, ref) {
  return null;
})

@workforbala
Copy link

any update on this issue ? we are facing same issue while upgrading formik ?

@Evaldoes
Copy link

To access formik by reference, you can do like this:

const formRef = useRef<FormikProps<FormProps>>(null);

<Formik innerRef={formRef} />

  • FormProps iis the model of the data that you will use in the form

image

image

If you print the reference console.log(formRef.current) you will see something like this:

image

This way it is possible to manipulate formik from anywhere 😄 😎 that's it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants