Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Form atoms for Jotai

License

NotificationsYou must be signed in to change notification settings

jotaijs/jotai-form

Repository files navigation

👻📃

Tweets

TOC

Install

The library can be simply installed by addingjotai-form to your dependencies

npm i jotai-form# oryarn add jotai-form# orpnpm add jotai-form

Note: The library depends onjotai so please make sure you have jotaiinstalled, if not you can do so by using the below commands

npm i jotai

Usage

Basic Usage

The very basic form of validation and the most common use case will involveusingatomWithValidate, which creates a similar atom tojotai

Thisatom can be used with theuseAtom helper but with a slight change. Thechange is that instead of directly giving you the state value you now have formbased properties

constform={  value,// the current value of the state  isDirty,// boolean value based on if the value has changed from the initial value  isValid,// boolean value representing if the current atom state is valid  error,// if an error was thrown from the validator, that'll be available here// and a conditional// boolean value when working with async validation, this// will be `true` for the duration of the validation and `false` once the validation is complete  isValidating,};

Note:isValidating will not be a property if you are using a synchronousvalidation function, your IDE should already help you with this but use thisproperty only when using asynchronous validation functions.

An example, combining all that information. You can find more such examples intheexamples folder

import{useAtom}from'jotai';import{atomWithValidate}from'jotai-form';import*asYupfrom'yup';// defining a validation schema for the atomconstemailSchema=Yup.string().email().required();// creating the atom with an async validation functionconstemailAtom=atomWithValidate('',{validate:async(v)=>{awaitemailSchema.validate(v);returnv;},});constForm=()=>{// Same API as other jotai atom's with the difference being// addition of form properties on `email`const[email,setEmail]=useAtom(emailAtom);return(<div><inputvalue={email.value}onChange={(e)=>setEmail(e.target.value)}/><span>{email.isValid&&'Valid'}</span><span>{!email.isValid&&`${email.error}`}</span></div>);};

Form Level Validation

You might have cases where you would like to validate the combination ofmultiple values.

Example, Maybe the combined name length of first and last names cannot exceed 15characters.

For this you can usevalidateAtoms which takes in a atom group and a validatorfunction which works very similar to theatomWithValidate's validate function.

The atom group validation atom is a read only atom and with similar propertiesas the atom returned fromatomWithValidate. The only change beingvaluesinstead ofvalue. This contains the passed atom group's values

Note: In most cases theatomWithValidate should suffice, form validationcomes into the picture when dealing with fields that do need a finalvalidation, the example here is one of the many cases but do not abuse formlevel validation.

Note:validateAtoms will not trigger each atom's internal validatefunctions, while adding disabled states or any other case where you need tocheck the atom's validity, please use the atom's ownisValid anderrorproperties.

import{useAtom}from'jotai';import{atomWithValidate,validateAtoms}from'jotai-form';import*asYupfrom'yup';constnameSchema=Yup.string().required();constfirstNameAtom=atomWithValidate('',{validate:async(v)=>{awaitnameSchema.validate(v);returnv;},});constlastNameAtom=atomWithValidate('',{validate:async(v)=>{awaitnameSchema.validate(v);returnv;},});constformGroup=validateAtoms({firstName:firstNameAtom,lastName:lastNameAtom,},(values)=>{if(values.firstName.length+values.lastName.length>15){thrownewError("Overall name can't be longer than 15 characters");}},);constForm=()=>{const[firstName,setFirstName]=useAtom(firstNameAtom);const[lastName,setLastName]=useAtom(lastNameAtom);const[formState]=useAtom(formGroup);return(<div><label>        firstName<inputvalue={firstName.value}onChange={(e)=>setFirstName(e.target.value)}/><span>{firstName.isValid&&'Valid'}</span><span>{!firstName.isValid&&`${email.error}`}</span></label><label>        lastName<inputvalue={lastName.value}onChange={(e)=>setLastName(e.target.value)}/><span>{lastName.isValid&&'Valid'}</span><span>{!lastName.isValid&&`${email.error}`}</span></label><buttondisabled={!formState.isValid||!firstName.isValid||!lastName.isValid}>        Submit</button>{// or// <button disabled={!(formState.isValid && firstName.isValid && lastName.isValid)}>Submit</button>}<span>{!formState.isValid&&`${formState.error}`}</span></div>);};

Form Controls

Added inv0.1.1

Form Group Validation usingvalidateAtoms is easier when the form is tinier and doesn't need much, but having multiple such hooks for a larger group of atoms might not be easy and lead to a lot of hooks.

We would like to keep the atomic approach but in case of forms it does need a little extension and so you can do so withatomWithFormControls.

Here's an example of what an example of this would look like.

Notes

  1. atomWithFormControls still expects aatomWithValidate group to be passed to it, this is so that you can still move and combine the same atom with otherform control groups if needed.
import{useAtom}from'jotai';import{atomWithValidate,validateAtoms}from'jotai-form';import*asYupfrom'yup';constnameSchema=Yup.string().required();constfirstNameAtom=atomWithValidate('',{validate:async(v)=>{awaitnameSchema.validate(v);returnv;},});constlastNameAtom=atomWithValidate('',{validate:async(v)=>{awaitnameSchema.validate(v);returnv;},});constformControlAtom=atomWithFormControls({firstName:firstNameAtom,lastName:lastNameAtom,},{validate:(values)=>{if(values.firstName!='jotai'){thrownewError("Oh well, can't let you in");}},},);functionFormComponent(){const{// Values per field    values,// is the form valid    isValid,// focused state per field    focused,// touched state per field    touched,// errors per field    fieldErrors,// form error    error,// handle change of value per field    handleOnChange,// handle blur event per field    handleOnBlur,// handle focus event per field    handleOnFocus,}=useAtomValue(formControlAtom);return(<><form><div><inputvalue={values.firstName}onChange={(e)=>{handleOnChange('firstName')(e.target.value);}}onFocus={handleOnFocus('firstName')}onBlur={handleOnBlur('firstName')}/><p>{fieldErrors.firstName&&touched.firstName              ?`${fieldErrors.firstName}`              :'Valid'}</p></div><div><inputvalue={values.lastName}onChange={(e)=>{handleOnChange('lastName')(e.target.value);}}onFocus={handleOnFocus('lastName')}onBlur={handleOnBlur('lastName')}/><p>{fieldErrors.firstName&&touched.firstName              ?`${fieldErrors.firstName}`              :'Valid'}</p></div><p>isValid:{isValid ?'Valid' :"Something's wrong"}</p><p>Form Error:{error?.toString()}</p></form></>);}

API

Primitives

atomWithValidate

atomWithValidate is the primary base for create validating atoms and it's state and validations are inferred by the other atoms in most cases.

atomWithValidate(initialValue,options);
paramdescriptiondefault
initialValueThe initial value of the atomundefined
options.validatefunction returning value orthrows an errorundefined
receives the current value of the atom.more...
options.areEqualfunction to compare the initial value to the changed valuesObject.is

Atom Curator Functions

validateAtoms

ThevalidateAtoms function accepts a group of primitives, in this caseatomWithValidate and a validator function for the entire group

validateAtoms(atomGroup,validator);
paramdescriptiondefault
atomGroupan object ofatomsWithValidate atomsundefined
the keys of the atomGroup are used as names/labels
when passed to thevalidator function
validatorfunction returning void orthrows an errorundefined
receives the atomGroup's values with the same keys.more...

atomWithFormControls

atomWithFormControls(atomGroup,options);
paramdescriptiondefault
atomGroupan object ofatomsWithValidate atomsundefined
the keys of the atomGroup are used as names/labels
when passed to thevalidator function
options.validatefunction returning void orthrows an errorundefined
receives the atomGroup's values with the same keys.more...

Validator Functions

While the API for the validator functions,options.validate orvalidator are very similar there's a few differences and also let's talk abouthow they work and what's the different

Rules

Things that apply to all the validator functions

  1. If the function executes without any error, the validation was successful.
  2. If there's any error , even something raised from an inner function, it'llmake the form invalid.
  3. Can pass in aasync / sync function for validation.
  4. The function will be passed the value of the atom that they are supposed tovalidate.options.validate fromatomWithValidate will get the value for it's own atom andvalidator,options.validate forvalidateAtoms andatomWithFormControls will get all the values from the passed inatomGroup)

Differences

  1. Primitive atoms expects you to return the value at the end of thevalidation to make sure the validation was run for the same value and yourstate and validated state doesn't have any mismatch.

  2. Curator Functions doesn't expect a return value since it acts as a listener to thegroup of atoms passed in and the values will not need the same state check, so you can just throw errors from it andif it doesn't return the values back there won't be a problem

Note: The keys of the object defined for the atomGroup is used as the keysfor thevalues that are passed to the atom curator functions, the same is applicableforatomWithFormControls

constatomGroup={name:nameAtom,age:ageAtom};constvalidator=(values)=>{values.name;// nameAtom's valuevalues.age;// ageAtom's value};validateAtoms(atomGroup,validator);atomWithFormControls(atomGroup,{validate:validator,});

About

Form atoms for Jotai

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors4

  •  
  •  
  •  
  •  

[8]ページ先頭

©2009-2025 Movatter.jp