Formik: Rename useFormik (and maybe useFormikContext)

Created on 1 Aug 2019  路  8Comments  路  Source: formium/formik

馃殌 Feature request

Current Behavior

Currently, useFormik is an internal hook used to initialize Formik, and useFormikContext is the hook used to actually use Formik functionality in user code. The problem is, when a user wants to "use Formik", they reasonably think, "duh, there's a useFormik hook! how simple!"

What I'm hearing around the issues here, is that the intended solution is simply to not export useFormik, and nobody will need to worry about it. However, I think useFormik can be useful if someone wants to take the core formik functionality and use it in a different context. I propose instead renaming these hooks to be more semantic and developer-friendly.

Desired Behavior

We want a developer who is about to try and "use formik" to be able to see the useFormik hook and know they can depend on it, or at least _not_ see a useFormik due to the internal hook being semantically named.

Suggested Solution

Rename the following hooks. These are suggestions which may not ultimately be what we settle on, but I think they move in the right direction.

useFormik: useFormikInitializer, useFormikCore, useFormikInternals, etc
useFormikContext: useFormik

Alias: useFormikContext -> useFormik in case users have already started using this. Add a development time deprecation warning.

Alternate Suggestion

Let there not be a useFormik hook at all, using useFormikInternals (or whatever) and useFormikContext.

Who does this impact? Who is this for?

Developers who want to "use Formik".

Describe alternatives you've considered

Answering dozens of questions about why useFormik doesn't work in Github Issues, Discord.

Additional context

I think this will solve a lot of headaches from misunderstandings in the community, while allowing the flexibility to initialize Formik and use it in a different React.Context.

Examples of the misconception in action

Note: Some of these may be my misreading since I glanced quickly through them.

https://github.com/jaredpalmer/formik/issues/1719#issuecomment-516048064
https://github.com/jaredpalmer/formik/pull/1717
https://github.com/jaredpalmer/formik/issues/1667
https://github.com/jaredpalmer/formik/issues/1666
https://github.com/jaredpalmer/formik/issues/1582
https://github.com/jaredpalmer/formik/issues/1571
https://github.com/jaredpalmer/formik/issues/1548
https://github.com/jaredpalmer/formik/pull/1063#discussion_r286970337

Formik v2

Most helpful comment

I came here to say this. Big thumbs up :+1: :+1: :+1:

All 8 comments

Yep

I came here to say this. Big thumbs up :+1: :+1: :+1:

Already done.

@jaredpalmer where I can find this changes? I use latest version of formik and still have possibility to import useFormik and useFormikContext

Instructions unclear :( I don't understand how to combine useFormik with useField (which required Context as far as I understand)

https://formik.org/docs/api/useFormik says: "Formik uses useFormik to create the component (which renders a React Context Provider). If you are trying to access Formik state via context, use useFormikContext."

But where / how do I use useFormikContext? I always get Warning: Formik context is undefined, please verify you are calling useFormikContext() as child of a <Formik> component. when calling useFormikContext.

const MyForm = () => {
  // useFormikContext() ?
  const formik = useFormik({
    initialValues: { name: "" },
    onSubmit: (values) => { console.log(values); }
  });

  return (
    <form onSubmit={formik.handleSubmit}>
      <MyField />
      <button type="submit">Submit</button>
    </form>
  );
}
const MyField = () => {
  // useFormikContext() ?
  const [field, meta, helpers] = useField("name");

  return (
    <input {...field} />
  );
}

@benneq the instructions say: Formik uses useFormik to create the component (which renders a React Context Provider)

By Formik, the instructions mean the <Formik /> component. The instructions describe a <Formik /> component that looks like this:

// Formik
const Formik = ({ children, ...formikProps }) => {
  // uses useFormik
  const formik = useFormik(formikProps);
  // to create the component which renders a React Context Provider
  return <FormikProvider value={formik}>{props.children}</FormikProvider>;
}

What this means is either, use <Formik /> or do the same thing above yourself. Anytime a FormikProvider appears as a parent of a functional component, that functional component can use useFormikContext().

Hooks can be hard to explain. Hope it helps!

@johnrom Thank you!

I do understand how hooks work. I was just kinda confused because of the sentence from the docs. I read "Formik" as "the library" and not as "the component". Maybe the docs should use <Formik /> or "The Formik component" instead of the ambiguous "Formik".

Of course I could have looked at the source code of the components and hooks, but that would have made the docs pointless 馃樇

I now use <Formik /> component everywhere, because reusable form components require Context. Now I can build simple and beautiful things like this:

const FormSubmitButton = (props) => {
    const formik = useFormikContext();

    return (
        <button type="submit" disabled={formik.isSubmitting} {...props} />
    );
};

馃憤

I agree we can change the documentation to read:

The <Formik /> component uses useFormik to render a React Context Provider, <FormikProvider />.

Feel free to open a quick PR. They can be links to the documentation for the specific components / hooks, though maybe that would be too many links.

Was this page helpful?
0 / 5 - 0 ratings