Add and/or document a simple useFormik hook.
To inject Formik properties into components, you have to rely on withFormik or connect.
export function SubmitButton({ component: Component = Button, ...rest }) {
const { isSubmitting, isValid, dirty } = useFormik();
return (
<Component
type="submit"
disabled={isSubmitting || !isValid || !dirty}
{...rest}
/>
);
}
I am using this simple piece of code:
import React, { useContext } from 'react';
import { FormikConsumer } from 'formik';
function useFormik() {
return useContext(FormikConsumer._context);
}
I am not sure whether this should be included in the code or simply be suggested in the documentation.
I favor just documenting it as a trick with all pertinent warnings as hooks itself is alpha and Formik itself relies in the soon to be obsolete create-react-context.
From the Formik user point of view, this is immediately useful, regardless of whether Formik itself uses hooks internally or not.
I've switched from using connect to useFormik and I'm happier as my Formik props are not merged along the other properties received by the component. I can deal with each set separately, making my code cleaner, making it clear where each set of properties comes from.
Yep. This has already been built in v2.
I'd have guessed as much, however, I don't know when 2.0 would be out and this useFormik works right now. As I said, I would rather have it as an item in a FAQ rather than actual code that has to be supported as it would, come 2.0.
Until v2, AFAICT this can be implemented in user land?
Absolutely, I am doing it with 1.3.2 and React 16.7.0 (alpha 2), it only needs documenting, to spare fellow developers the trouble.
It could be better supported by changing these lines: https://github.com/jaredpalmer/formik/blob/2.0/src/connect.tsx#L6-L9 , and exposing the Context object with its own export, but if it is coming in v2.0, then it isn't worth the trouble.
I am hesitant to introduce docs that tell people to write functions that may have conflicting names with v2 release. See #1005
It depends. If the signature of the suggested hook is the same as the one that will be available in v2, it would serve as a preview of v2. Switching from one to the other would be a simple search and replace from
import useFormik from './patches/useformik.js'
// to:
import { /* whatever else was already there */, useFormik} from 'formik';
Basically, add // in front of every import useFormik and add ,useFormik麓 after anyFormiknot preceded by<or`.
If the signature would not be the same and/or v2 is right around the corner then, I agree, it's not worth the trouble. Anyway, hooks is still alpha so whomever uses any form of hooks knows API changes are likely.
And either way, this issue might serve as documentation enough for the adventurous. So, I guess, this item may be closed.
Thanks
@Satyam I'm trying this hook and noticed that the default webpack production settings renames _context when minifying. I tried marking it as "reserved" in the terser options, but that didn't seem to help. Did you run into this as well?
Update (for anyone else trying this): React only adds _context to Consumer in dev mode; in order to use this in production you will need to use FormikProvider._context instead of FormikConsumer._context to get the context.
I'm afraid that the project in which I was using useFormik never went into production so I had never run it out of development mode. Sorry and thanks for the fix.
why not export FormikContext?
@jaredpalmer Because of compiler optimizations we really need that FormikContext to be exported rather than just the consumer. This will let us write our own hooks! Any help on this would be very appreciated.
One possible workaround:
const FormikContextHack = React.createContext({});
export function FormikHack({ children, render, ...rest }) {
return (
<Formik {...rest}>
<FormikConsumer>
{value => {
return (
<FormikContextHack.Provider value={value}>
{render ? render(value) : children}
</FormikContextHack.Provider>
);
}}
</FormikConsumer>
</Formik>
);
}
FormikHack.propTypes = Formik.propTypes;
export function useFormik() {
return useContext(FormikContextHack);
}
Most helpful comment
why not export
FormikContext?