Intro to Jotai. Part 1
Intro to Jotai. Part 2
Creating derived atoms is easy and useful. From one data source you can create many atoms. They allow to transform source data, or create new information based on it. Derived atoms are your first tool to structure your data models, and to control your UI state.
You already created simple form with one input and validation. Now let’s add another input with validation and submit button. Later, we can use validation atoms to decide whether user can submit the form. In this part, you’ll also switch from bare HTML elements to Material UI.
import TextField from "@mui/material/TextField";
const Input = ({ type = "text", label, sourceAtom }: InputProps) => {
const [text, setText] = useAtom(sourceAtom);
return (
<TextField
type={type}
label={label}
variant="filled"
value={text}
onChange={(e) => setText(e.target.value)}
/>
);
};
Let’s use new version of Input
component and create inputs for name and password.
const nameAtom = atom("John");
const passwordAtom = atom("");
const Form = () => {
return (
<Box
component="form"
sx={{
"& > :not(style)": { m: 2, width: "25ch" }
}}
>
<Typography variant="h3" gutterBottom>
Registration form
</Typography>
<Input label="Name" sourceAtom={nameAtom} />
<Input type="password" label="Password" sourceAtom={passwordAtom} />
</Box>
);
};
Source atoms are ready. Next step is creating derived validation atoms.
const nameLengthAtom = atom((get) => get(nameAtom).length);
const passwordLengthAtom = atom((get) => get(passwordAtom).length);
const isNameValid = atom((get) => get(nameLengthAtom) >= 3);
const isPasswordValid = atom((get) => get(passwordLengthAtom) >= 3);
Because you want to control whether user can submit a form we need one more atom. It’s a general atom describing whether whole form is in valid state.
const isFormValid = atom((get) => get(isNameValid) && get(isPasswordValid));
This atom derives values from name and password validation atoms and joins those values together. Using this new atom you’re ready to create submit button.
const SubmitButton = () => {
const isValid = useAtomValue(isFormValid);
return (
<Box>
<Button disabled={!isValid} variant="outlined">
Register
</Button>
</Box>
);
};
If form is valid submit button is ready to click. If form is invalid button is disabled. Simple.
Let’s see how full form looks now.
const Form = () => (
<Box
component="form"
sx={{
"& > :not(style)": { m: 2, width: "25ch" }
}}
>
<Typography variant="h3" gutterBottom>
Registration form
</Typography>
<Input label="Name" sourceAtom={nameAtom} />
<Input type="password" label="Password" sourceAtom={passwordAtom} />
<Error sourceAtom={isNameValid} errorInfo="Name is too short" />
<Error sourceAtom={isPasswordValid} errorInfo="Password is too short" />
<SubmitButton />
</Box>
);
This form also uses new, general Error
component to display particular errors. Check out full code to see source of this component.
As always check out Jotai website for docs and more examples of Jotai code.
Top comments (0)