formik icon indicating copy to clipboard operation
formik copied to clipboard

Formik v3 Umbrella PR.

Open johnrom opened this issue 3 years ago • 28 comments

Note: Formik no longer appears maintained, but I am leaving this PR open for archival purposes.

closes #3099

Todo:

  • [x] Merge main
  • [x] React Native Batching
  • [ ] Documentation

johnrom avatar Jun 04 '21 19:06 johnrom

🦋 Changeset detected

Latest commit: a38ded48a3572f2737224551e7826d7ea9030958

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

changeset-bot[bot] avatar Jun 04 '21 19:06 changeset-bot[bot]

@johnrom is attempting to deploy a commit to the Formium Team on Vercel.

A member of the Team first needs to authorize it.

vercel[bot] avatar Jun 04 '21 19:06 vercel[bot]

is there any plan to continue this?

Mikoz93 avatar Jul 23 '21 15:07 Mikoz93

This PR is complete so far as I know, just needs documentation. I don't plan to make any more changes until this is merged or specific changes within scope are requested.

johnrom avatar Jul 23 '21 19:07 johnrom

@jaredpalmer I made a change here to use unstable_batchedUpdates but I don't know how to configure tsdx to create an alternate index.native.js entrypoint.

Any ideas??

johnrom avatar Aug 12 '21 19:08 johnrom

It's not possible at the moment. Is this to support formik-native or to just support formik in react native w/new react APIs?

jaredpalmer avatar Aug 26 '21 11:08 jaredpalmer

This is ready to merge imho

jaredpalmer avatar Aug 26 '21 11:08 jaredpalmer

@jaredpalmer it isn't ready to merge until we solve the issue of building a React Native version w/ import { unstable_batchedUpdates } from 'react-native';

This is to support React Native because the initial version where we used a Layout Effect to trigger updates to subscriptions could cause an infinite loop with code that would test "props.value" and "prevProps.value" and if it changed, trigger an update to Formik's field value. The next render would be prevValue, then trigger a layout update, updating to value, but the downstream component would have already updated the value back to prevValue. I think this extra invisible render might cause a lot of issues for people, but the below issue is just one example:

https://github.com/formium/formik/issues/2968

The PR as it is would work in any other build process, webpack or whatever, with no issue. However, with tsdx I can't do the kind of transforms I would do with webpack in like 3 minutes.

The only workaround I came up with was manually implementing this into TSDX: https://github.com/formium/tsdx/issues/746 and then running this ridiculous build process.

This resulted in

index.js -> batchedUpdates = import { unstable_batchedUpdates } from 'react-dom' index.native.js -> const batchedUpdates = import { unstable_batchedUpdates } from 'react-native' index.alternate.js -> const batchedUpdates = (callback) => callback()

However, it didn't work in the expo snack, so I don't think I know enough about Metro (I have never used RN IRL) to get it working at the moment. The snack doesn't let you explore node_modules so it's possible the publish just didn't work right.

I tried setting up a project locally but tbh the yarn installs for Formik + Yarn + WorkSpace + React Native take so long that I just didn't have time to experiment further.

Another workaround would be to split Formik into formik, formik-native, and formik-core, where formik itself would just be

export * from 'formik-core';
import { setBatch } from 'formik';
import { unstable_batchedUpdates } from 'react-dom';

setBatch(unstable_batchedUpdates);

And formik-core would be exactly what Formik is now, sans batching.

We could alternatively make formik only build index.js and index.alternate.js, make formik-native import formik/index.alternate.js, which is probably the best of both worlds, but I don't know when I'd have time to get this done. Then, we'd be able to push Formik v3 while keeping Formik-Native v2 until we solve the issue (assuming nobody imports formik directly into RN projects, which is probably a bad assumption).

johnrom avatar Aug 26 '21 14:08 johnrom

@johnrom At work we use react-native-web to do cross platform UI and also use formik. We def import formik directly for usage on react-native right now. I totally understand if that is a breaking change, but it would be nice if there was some way around that and we could keep using formik directly.

jonstuebe avatar Sep 11 '21 16:09 jonstuebe

@jonstuebe yeah, I have been experimenting with the metro compiler and setting up Formik to build a version with a React native suffix like index.native.js, but I haven't had much time to work on it.

johnrom avatar Sep 11 '21 17:09 johnrom

@jonstuebe yeah, I have been experimenting with the metro compiler and setting up Formik to build a version with a React native suffix like index.native.js, but I haven't had much time to work on it.

It may have to be done through aliasing the import name similar to webpack aliases but just through metro instead

jonstuebe avatar Sep 11 '21 17:09 jonstuebe

I published a fix for this that requires zero developer intervention in Metro / Expo. It uses an ugly tsdx workaround to generate multiple Formiks, chooses a custom one via "react-native" field in package.json, and creates a third version at /dist/index.alternate.js for people who use neither batching system.

Not being a React Native dev, I'm not certain how the majority of developers use React Native, so I think we should do an official release candidate phase for these changes or get someone's eyes on here that are a little better than mine.

https://snack.expo.dev/@johnrom/trembling-tortillas

NPM packages:

@johnrom/[email protected] @johnrom/[email protected]

For some reason when using formik-native in SubmitButton in the above Snack, it's not able to pick up on Formik's context and call submitForm. However, when I run it via expo on my phone, it works fine. I'm wondering if whatever build process the Snack uses isn't picking up on the "react-native" package.json field.

If this doesn't work, we'd have to drop TSDX or modify it heavily to get it to work, so we can generate formik.cjs.native.js.

johnrom avatar Sep 12 '21 19:09 johnrom

Another alternative to splitting up formik would be to make formik not handle the batching implementation and require everyone explicitly declare the batching implementation based on their react renderer. i.e. By requiring that import either 'formik/dom'; or import 'formik/native'; is imported once in the application to set the batching implementation.

We could clean up formik slightly while making this feel "automatic" for the DOM case by moving <Form> to formik/dom. That would remove the code for <Form> (which outputs a <form> that only works with react-dom) from any unoptimized native bundles while also making it so anyone who happens to use the useful <Form> helper also implicitly sets up the react-dom renderer batching.

dantman avatar Oct 21 '21 05:10 dantman

This is done and works just as it did before (no splitting) using the "react-native" field in package.json. I just don't use React Native so I don't know whether that works in all RN environments. I tested with expo.

Basically RN folks should review it or we should release an RC with this PR. However, I haven't heard anything from Jared in months so I just continued using my fork until my next project when I may have to officially fork it.

The naming convention I would use if it needed a split is @formik/react-dom and @formik/react-native as the Formik internals themselves could apply to almost any environment. They would both pull from @formik/core which could be used in any framework. (I did this anyway at first, but decided it probably wouldn't pass the PR)

johnrom avatar Oct 21 '21 14:10 johnrom

Hi, do you have any plans with that v3 version? Or maybe you need some help?

We would like to use v3 in our application and try to figure out what is the best way to do so.

kuzaxak avatar Jan 23 '22 23:01 kuzaxak

@kuzaxak this PR is complete as far as I know. I requested Formik release it as an official RC so it can get more testing done, but there has been no movement there. Unfortunately I'm fully loaded up on client work at the moment, so I haven't decided where to go next.

johnrom avatar Jan 24 '22 15:01 johnrom

Would love to see the RC published! I have a decent size monorepo that I can help test things on and give feedback on perf and such.

jonstuebe avatar Jan 24 '22 16:01 jonstuebe

@kuzaxak this PR is complete as far as I know. I requested Formik release it as an official RC so it can get more testing done, but there has been no movement there. Unfortunately I'm fully loaded up on client work at the moment, so I haven't decided where to go next.

I see that you published it as rc under your own npm package, can we use it? Or we need to use git dependency?

kuzaxak avatar Jan 24 '22 17:01 kuzaxak

Feel free to test my RC via npm with @johnrom/[email protected] in order to test and add any issues you may find here, with the following caveats:

  • I will not be providing support to individuals for my RC; any issues you find may or may not be resolved in a timely fashion.
  • Some things are not very well-documented and I probably won't find too much time to answer questions either. The API should be backwards compatible with Formik for the most part with some minor variations (useFormikState, useFormikContext and useFormikConfig have been split). You'll probably need to run through this PR and find subtle differences on your own. The Types will help to identify where pieces of Formik come from in the new system. The helper components like Formik, Form, Field, and ErrorMessage should work just as they did before.
    • for your convenience, here are the docs that I started for my RC. unfortunately, I haven't had time to work on them, but all of the examples have been updated in the code. https://github.com/johnrom/formik/pull/11
  • The current npm package is a placeholder because I wanted to make it clear that it's not meant to be a production version. If it were eventually released you'd have to switch back to the final released package.
  • I am not a maintainer of Formik so this PR should not be a general issue repository for Formik itself, only issues with the specific changes made to this PR.

johnrom avatar Jan 24 '22 17:01 johnrom

Feel free to test my RC via npm with @johnrom/[email protected] in order to test and add any issues you may find here, with the following caveats:

  • I will not be providing support to individuals for my RC; any issues you find may or may not be resolved in a timely fashion.

  • Some things are not very well-documented and I probably won't find too much time to answer questions either. The API should be backwards compatible with Formik for the most part with some minor variations (useFormikState, useFormikContext and useFormikConfig have been split). You'll probably need to run through this PR and find subtle differences on your own. The Types will help to identify where pieces of Formik come from in the new system. The helper components like Formik, Form, Field, and ErrorMessage should work just as they did before.

    • for your convenience, here are the docs that I started for my RC. unfortunately, I haven't had time to work on them, but all of the examples have been updated in the code. v3 docs johnrom/formik#10
  • The current npm package is a placeholder because I wanted to make it clear that it's not meant to be a production version. If it were eventually released you'd have to switch back to the final released package.

  • I am not a maintainer of Formik so this PR should not be a general issue repository for Formik itself, only issues with the specific changes made to this PR.

This is totally understandable :)

If we will find some problems we always can fork your fork and propose a change. Thank you for your answers and the work you did!

kuzaxak avatar Jan 24 '22 18:01 kuzaxak

I updated my previous comment to use the correct PR for the documentation. The previous one was the wrong branch. The new PR is here: https://github.com/johnrom/formik/pull/11

johnrom avatar Jan 24 '22 18:01 johnrom

@jaredpalmer Is there any plan to move this forward? It seems like from the original Todo's, only the documentation remains to be complete. Thanks for your time!

Mikoz93 avatar Jan 29 '22 00:01 Mikoz93

@johnrom Just letting you know the published @johnrom/[email protected] package has an incorrect module field in package.json.

Im having trouble using this in place of my existing installation, since useSetFieldValue is not exported. I think probably cos my project is based on top of the beta in main, this isnt reflected in this PR?

adam-thomas-privitar avatar Mar 31 '22 17:03 adam-thomas-privitar

@adam-thomas-privitar you don't have to use the micro-hooks, you can use useFormikContext().setFieldValue.

The micro-hooks are from the original v3 PR Jared created which optimized the hooks a different way. This one instead removes state from useFormikContext which makes it a stable hook which will not trigger re-renders.

I'll take a look at the package.json when I get a chance.

johnrom avatar Mar 31 '22 17:03 johnrom

The module issue should be fixed in 3.0.0-rc2.

With the updated module, you can do this after node modules are installed:

import { useField } from '@johnrom/formik-v3';

const MyField = (props) => {
  const [field] = useField(props);

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

johnrom avatar Mar 31 '22 18:03 johnrom

@adam-thomas-privitar you don't have to use the micro-hooks, you can use useFormikContext().setFieldValue.

The micro-hooks are from the original v3 PR Jared created which optimized the hooks a different way. This one instead removes state from useFormikContext which makes it a stable hook which will not trigger re-renders.

I'll take a look at the package.json when I get a chance.

Yeh I suspected as much! Sadly...Im based on the v3 beta and so have a fair amount of code on top of the "new" hooks. I will need to do a bit more refactoring.

Thanks for fixing the module issue.

adam-thomas-privitar avatar Apr 01 '22 21:04 adam-thomas-privitar

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployments, click below or on the icon next to each commit.

formik-docs – ./

🔍 Inspect: https://vercel.com/jared/formik-docs/2LvHDxC73yoFJbQhSLohVRBq3oDr
✅ Preview: Failed

vercel[bot] avatar Apr 15 '22 20:04 vercel[bot]

@quantizor, noticed you approved a PR for a release that went out a few days ago. This might be great to consider approving, as I've run into https://github.com/jaredpalmer/formik/issues/3335 myself! I'm happy to make any changes necessary to resolve any merge conflicts.

leoriviera avatar Apr 29 '24 12:04 leoriviera