JotaiでFormを作る
1つのFieldごとにatomを定義する
code:ts
import { atom, useAtom, useAtomValue } from 'jotai';
import { TextField } from 'app/src/utils/form/components/TextField';
export const widthAtom = atom<Width>(200);
const parsedAtom = atom(get => {
const raw = get(widthAtom);
return validate.safeParse(raw);
});
export const WidthField: React.FC = () => {
const result = useAtomValue(parsedAtom);
const errorMessage = result.success
? undefined
: result.error.issues0?.message; return (
<>
<label htmlFor="width">width</label>
<TextField
value={value}
onChange={e => onChange(+e.target.value)}
id="width"
type="number"
error={errorMessage}
/>
</>
);
};
1つ1つが小さいのでかなり応用が効く
前のfieldに依存した値を表示するfieldとか
schemaを定義しないので設置場所を移動しやすい
composabityが高い
isDirtyとかのフラグが欲しくなればそれもatomで用意すれば良い
2023年頃に業務で作ってたform過多のツール系のプロダクトで採用した
react-hook-formでやってると完全に破綻していたと思うmrsekut.icon
初期値がないとき
ふつうにこう
code:ts
export const hogeAtom = atom<Price | null>(null);
初回にvalidation errorを出したくないとき
code:ts
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setIsDirty(true);
onChange(e.target.value);
};
const result = useAtomValue(parsedAtom);
const errorMessage =
result.success || !isDirty ? undefined : result.error.issues0?.message; type=numberにはしないが数値のみが正しいとき
fieldの中ではstringのみを参照する
正しいhogeAtomのために型変換とエラーを表示
そうしないと、文字を入力するとUI上の表示がNaNになってしまう
ペライチの、特に何も複雑なことをしないようなformを並べるとき
例えばお問い合わせフォームみたいに、fieldを数個置いて、validation書いて、送信、みたいな単純なやつ
複数のfieldの値を使って計算してゴニョゴニョ、というのは向いてない