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

RFC: DX Improvements #20

Closed
barelyhuman opened this issue Nov 25, 2023 · 8 comments
Closed

RFC: DX Improvements #20

barelyhuman opened this issue Nov 25, 2023 · 8 comments
Assignees
Labels
rfc Request for Comments

Comments

@barelyhuman
Copy link
Collaborator

jotai-form has been out for more than a year now
and the additions of form control helpers has been here for a few months now. I'd like to gather up the users of jotai form to let us know of how we can help you have better experience using Jotai form.

We'd like answers for the following questions.

  1. What the most counter intuitive thing while using jotai-form + jotai
  2. What kind of logic do you think is unnecessary and could've been hidden from the userland code
  3. Anything else you wish that jotai-form also handled or created helpers for
@barelyhuman barelyhuman added the rfc Request for Comments label Nov 25, 2023
@barelyhuman barelyhuman self-assigned this Nov 25, 2023
@Odonno
Copy link
Contributor

Odonno commented Nov 25, 2023

Hello there,

First of all, thank you for taking your time in maintaining this interesting project.

I recently discovered this project and used it in an example project where I needed to deal with 2 simple forms (using atomWithFormControls). I used Zod for schema validation as it is the main trend at the moment.

My first impression was having a really simple and intuitive DX, when you already know jotai. It covered the basic features I needed.

Also it feels like a lot of code but I can't tell the difference with other libraries for now. It is not really a good/bad argument since everything can be encapsulated in the same file. Having validation schema + atoms + form component in the same file is a must-have.

I think the most pain points for using this lib is the lack of features. The ones I can think of at the moment:

  • having a close feature parity with react-hook-form. I am talking about "generic" features that can used on any validation libraries, like focus on first error when submitting form. This can be debattable as most features requires a ref to the form or each component.
  • handling form/atom reset, maybe with reset on component lifecycle (mount/unmount), might be the top priority feature
  • would it be possible to provide a less boilerplate API? Where you only have to define an object schema (with Zod for example) and it infers the atoms/atomWithValidate based on the schema? I suppose that would need a plugin ecosystem, like jotai-form-zod, etc...
  • the safeValidate/safeValidateAsync as you already saw in my current PR, to work with safeParse function

On a final note, the readme feels a little overwhelming. That can be interesting to extend the documentation and integrate it in the official jotai website. And then having a simplified introduction in the readme.

Keep the good work.

@barelyhuman
Copy link
Collaborator Author

barelyhuman commented Nov 25, 2023

having a close feature parity with react-hook-form. I am talking about "generic" features that can used on any validation libraries, like focus on first error when submitting form. This can be debattable as most features requires a ref to the form or each component

That would make this library dependent on the UI library you use so a more vanilla js approach for that is something we can do but then it's no more form state management but a form UI management, it's a nice suggestion so we might add it as a separate library that works with this one

handling form/atom reset, maybe with reset on component lifecycle (mount/unmount), might be the top priority feature

This should be doable, as a react specific helper, though the library isn't react specific. The examples are, the library isn't. Overall, we should be able to add this into a /react import in the future

would it be possible to provide a less boilerplate API? Where you only have to define an object schema (with Zod for example) and it infers the atoms/atomWithValidate based on the schema? I suppose that would need a plugin ecosystem, like jotai-form-zod, etc...

nice reminder, I do have a tiny function that I use, I should be able to add that into jotai-form

On a final note, the readme feels a little overwhelming. That can be interesting to extend the documentation and integrate it in the official jotai website. And then having a simplified introduction in the readme

We weren't sure of the current userbase as there's no way to know if people are using it or not and the amount of numbers online aren't a good measure either, I plan on adding a tiny website which would be easier to browse but let me confirm with @dai-shi if we plan on adding documentation for these into https://jotai.org

@MiroslavPetrik
Copy link

Have you seen form-atoms? It has good DX and for me is go-to jotai form.
I'm also a contributor, and I've built several advanced cases for the form in @form-atoms/field.
E.g. ListField, RadioGroup or CheckboxGroup all headless components which you won't find easily in other react libraries.

Something close to this is FormKit available in vue (I've never used, but from skimming the docs I like their DX as well)

@dai-shi
Copy link
Member

dai-shi commented Nov 26, 2023

We weren't sure of the current userbase as there's no way to know if people are using it or not and the amount of numbers online aren't a good measure either, I plan on adding a tiny website which would be easier to browse but let me confirm with @dai-shi if we plan on adding documentation for these into https://jotai.org

Please see my comment in pmndrs/jotai#2260 (comment).
Currently, jotai-form is a third-party library, but I think we can consider to make it semi-official. Maybe after collecting feedback in this RFC, and doing some improvements?

@barelyhuman
Copy link
Collaborator Author

I'd like to wait for more feedback so I can add in priorities to what needs to be added accordingly.

@daniel-rodrigue
Copy link

For my part, I wanted to kick out react-form-hook and replaced it with something different. The main reason is I had multiple performance issues with that library (too many re-renderings due to how react-form-hook's context provider works). I tried different ways to optimize my code without any success. I decided on jotai (and now jotai-form to support validations). What a huge difference it made! I'm not going back.

Now, as I wanted to add validations to my new jotai-based code, I realized that I could not easily add validations with jotai-form.

Here's the explanation. My code was based on this approach (and using jotai-optics):

const defaultForm: MyForm = {
  name: "",
  description: "",
  (...)
  // and about 60 more fields...
};

const formAtom = atomWithReset<MyForm>(defaultForm); // I needed reset feature
const nameAtom = focusAtom(formAtom, (o) => o.prop("name")); // for each field in my form
// etc.

Now I want to add validation, let's say value is required, to this atom with atomWithValidate(). That did go very far since passing an atom does not give you the value by reading your atom with a get.

In the end, I removed jotai-optics completely, let jotai-form hold the values for me and keep these atoms in a different interface.

It could be interesting to see if atomWithValidate could supports atoms. Something like:

// not sure what to do with initialValue here... maybe 1st read of the atom is the initial value?
const nameValAtom = atomWithValidate<Atom<string>, string>(nameAtom, {
  validate: (value) => ...
});

value in validate is the result of get(atom) and would store the value by using set(atom, validatedValue).

Food for thoughts. And amazing job!

@daniel-rodrigue
Copy link

daniel-rodrigue commented Mar 11, 2024

Here's another enhancement request. When the validate() callback is executed, it would be nice if the read atom's get() would be passed to it. This would make the validation even more useful when, for example, the validation of one value depends on another atom's value.

The validate() would be defined as:

validate: (value: Value, get: Getter) => Value; // or Promise<Value> for async

As an example, a validate function could show errors only when the form has been submitted:

const submittedAtom = atom<boolean>(false);
const fieldAtom = atomWithValidate<string>("", {
  validate: (value, get) => {
    const submitted = get(submittedAtom);
    if (submitted && value === "") {
      throw new Error("Field is required.");
    }
    return value;
  }
});

@barelyhuman
Copy link
Collaborator Author

That's quiet a bit of features to pick up so closing this now

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

No branches or pull requests

5 participants