fielder
Version:
A field-first form library for React and React Native
153 lines (118 loc) • 3.59 kB
text/mdx
# Getting started
_Creating a form and fields with `Fielder`._
## Creating a form
Every form starts in the same way - a root "form" component to:
- Create an instance of `Fielder`
- Expose that instance to any child components
```tsx
import React, { useEffect } from 'react';
import { useForm, FielderProvider } from 'fielder';
const LoginForm = ({ children }) => {
const formState = useForm();
// Example of reacting to form changes
useEffect(() => {
console.log('Form state has changed!', formState);
}, [formState]);
return <FielderProvider value={formState}>{children}</FielderProvider>;
};
```
The use of `FielderProvider` ensures that the hooks we use later can access the form state.
> Forms can be a static section on a page, or a dynamic collection of pages (i.e. steppers/wizards/multi-step).
## Adding some fields
Next we want to add some fields to our form.
> It's important to remember that fielder treats fields as dynamic entities. This means they can be added, removed, and/or changed at any time.
```tsx
const MyFormContent = () => {
const [usernameProps] = useField({
name: 'username',
initialValue: '',
});
const [passwordProps] = useField({
name: 'password',
initialValue: '',
});
return (
<form>
<input type="text" {...usernameProps} />
<input type="password" {...passwordProps} />
</form>
);
};
```
## Checkbox & Radio inputs
Checkbox and radio inputs are different to all other field types as their state is declared by the `checked`
attribute rather than `value` ([more info here](https://github.com/andyrichardson/fielder/issues/23#issuecomment-576352847)).
### Radio buttons
Using radio buttons is similar to using text fields, with two exceptions:
- The `value` attribute is static
- The `checked` attribute needs to be added (see below)
```tsx
const [hobbiesProps] = useField({
name: 'hobbies',
initialValue: 'sports',
});
const radioButtons = useMemo(() => [
{ label: "Sports", value: "sports" },
{ label: "Coding", value: "coding" },
{ label: "Other", value: "other" },
], []);
return (
<>
<p>What is your favorite hobby?</p>
{radioButtons.map(({ label, value }) => (
<input
key={value}
type="radio"
{...hobbiesProps}
value={value}
checked={hobbiesProps.value === value}
/>
{label}
))}
</>
)
```
### Checkbox groups
Checkbox groups are a means for storing multiple checkbox selections in a single field.
These are almost identical to radio buttons - the only difference being their value is an array corresponding to the selected values.
```tsx
const [hobbiesProps] = useField({
name: 'hobbies',
initialValue: ['sports'],
});
const checkboxOptions = useMemo(() => [
{ label: "Sports", value: "sports" },
{ label: "Coding", value: "coding" },
{ label: "Other", value: "other" },
], []);
return (
<>
<p>What are your hobbies?</p>
{checkboxOptions.map(({ label, value }) => (
<input
key={value}
type="checkbox"
{...hobbiesProps}
value={value}
checked={hobbiesProps.value.includes(value)}
/>
{label}
))}
</>
)
```
### Checkboxes (individual)
If you prefer to have a field for each checkbox, that's also an option.
Be sure to set the initial value of the field to boolean.
```tsx
const [acceptProps] = useField({
name: 'accept',
initialValue: false,
});
return (
<>
<p>Do you accept these terms?</p>
<input type="checkbox" {...acceptProps} checked={acceptProps.value} />
</>
);
```