Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d0d7602
commit af0c7d0
Showing
5 changed files
with
1,473 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
--- | ||
id: version-2.0.4-useField | ||
title: useField() | ||
custom_edit_url: https://github.com/jaredpalmer/formik/edit/master/docs/api/usefield.md | ||
original_id: useField | ||
--- | ||
|
||
`useField` is a custom React hook that will automagically help you hook up inputs to Formik. You can and should use it to build your own custom input primitives. There are 2 ways to use it. | ||
|
||
## Example | ||
|
||
```tsx | ||
import React from 'react'; | ||
import { useField, Formik } from 'formik'; | ||
|
||
const MyTextField = ({ label, ...props }) => { | ||
const [field, meta] = useField(props); | ||
return ( | ||
<> | ||
<label> | ||
{label} | ||
<input {...field} {...props} /> | ||
</label> | ||
{meta.touched && meta.error ? ( | ||
<div className="error">{meta.error}</div> | ||
) : null} | ||
</> | ||
); | ||
}; | ||
|
||
const Example = () => ( | ||
<div> | ||
<h1>My Form</h1> | ||
<Formik | ||
initialValues={{ email: '', firstName: 'red', lastName: '' }} | ||
onSubmit={(values, actions) => { | ||
setTimeout(() => { | ||
alert(JSON.stringify(values, null, 2)); | ||
actions.setSubmitting(false); | ||
}, 1000); | ||
}} | ||
render={(props: FormikProps<Values>) => ( | ||
<form onSubmit={props.handleSubmit}> | ||
<MyTextField name="firstName" type="text" label="First Name" /> | ||
<MyTextField name="lastName" type="text" label="Last Name" /> | ||
<MyTextField name="email" type="email" label="Email" /> | ||
<button type="submit">Submit</button> | ||
</form> | ||
)} | ||
/> | ||
</div> | ||
); | ||
``` | ||
|
||
--- | ||
|
||
# Reference | ||
|
||
## `useField<Value = any>(name: string | FieldAttributes<Val>): [FieldInputProps<Value>, FieldMetaProps<Value>]` | ||
|
||
A custom React Hook that returns a tuple (2 element array) containing `FieldProps` and `FieldMetaProps`. It accepts either a string of a field name or an object as an argument. The object must at least contain a `name` key. This object should identical to the props that you would pass to `<Field>` and the returned helpers will mimic the behavior of `<Field>` exactly. This is useful, and generally preferred, since it allows you to take advantage of formik's checkbox, radio, and multiple select behavior when the object contains the relevant key/values (e.g. `type: 'checkbox'`, `multiple: true`, etc.). | ||
|
||
```jsx | ||
import React from 'react'; | ||
import { useField } from 'formik'; | ||
|
||
function MyTextField(props) { | ||
// this will return field props for an <input /> | ||
const [field, meta] = useField(props.name); | ||
return ( | ||
<> | ||
<input {...field} {...props} /> | ||
{meta.error && meta.touched && <div>{meta.error}</div>} | ||
</> | ||
); | ||
} | ||
|
||
function MyInput(props) { | ||
// this will return field exactly like <Field>{({ field }) => ... }</Field> | ||
const [field, meta] = useField(props); | ||
return ( | ||
<> | ||
<input {...field} {...props} /> | ||
{meta.error && meta.touched && <div>{meta.error}</div>} | ||
</> | ||
); | ||
} | ||
``` | ||
|
||
### `FieldInputProps` | ||
|
||
An object that contains: | ||
|
||
- `name: string` - The name of the field | ||
- `checked?: boolean` - Whether or not the input is checked, this is _only_ defined if `useField` is passed an object with a `name`, `type: "checkbox"` or `type: radio`. | ||
- `onBlur: () => void;` - A blur event handler | ||
- `onChange: (e: React.ChangeEvent<any>) => void` - A change event handler | ||
- `value: any` - The field's value (plucked out of `values`) or, if it is a checkbox or radio input, then potentially the `value` passed into `useField`. | ||
- `multiple?: boolean` - Whether or not the multiple values can be selected. This is only ever defined when `useField` is passed an object with `multiple: true` | ||
|
||
### `FieldMetaProps` | ||
|
||
An object that contains relevant computed metadata about a field. More specifically, | ||
|
||
- `error?: string` - The field's error message (plucked out of `errors`) | ||
- `initialError?: string` - The field's initial error if the field is present in `initialErrors` (plucked out of `initialErrors`) | ||
- `initialTouched: boolean` - The field's initial value if the field is present in `initialTouched` (plucked out of `initialTouched`) | ||
- `initialValue?: any` - The field's initial value if the field is given a value in `initialValues` (plucked out of `initialValues`) | ||
- `touched: boolean` - Whether the field has been visited (plucked out of `touched`) | ||
- `value: any` - The field's value (plucked out of `values`) |
140 changes: 140 additions & 0 deletions
140
website/versioned_docs/version-2.0.4/guides/typescript.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
--- | ||
id: version-2.0.4-typescript | ||
title: TypeScript | ||
custom_edit_url: https://github.com/jaredpalmer/formik/edit/master/docs/guides/typescript.md | ||
original_id: typescript | ||
--- | ||
|
||
[![TypeScript Types](https://img.shields.io/npm/types/formik.svg)](https://npm.im/formik) | ||
|
||
The Formik source code is written in TypeScript, so you can rest easy that Formik's | ||
types will always be up-to-date. As a mental model, Formik's type signatures are very | ||
similar to React Router 4's `<Route>`. | ||
|
||
#### Render props (`<Formik />` and `<Field />`) | ||
|
||
```typescript | ||
import * as React from 'react'; | ||
import { | ||
Formik, | ||
FormikHelpers, | ||
FormikProps, | ||
Form, | ||
Field, | ||
FieldProps, | ||
} from 'formik'; | ||
|
||
interface MyFormValues { | ||
firstName: string; | ||
} | ||
|
||
export const MyApp: React.FC<{}> = () => { | ||
const initialValues: MyFormValues = { firstName: '' }; | ||
return ( | ||
<div> | ||
<h1>My Example</h1> | ||
<Formik | ||
initialValues={initialValues} | ||
onSubmit={(values, actions) => { | ||
console.log({ values, actions }); | ||
alert(JSON.stringify(values, null, 2)); | ||
actions.setSubmitting(false); | ||
}} | ||
render={formikBag => ( | ||
<Form> | ||
<Field | ||
name="firstName" | ||
render={({ field, form, meta }) => ( | ||
<div> | ||
<input type="text" {...field} placeholder="First Name" /> | ||
{meta.touched && meta.error && meta.error} | ||
</div> | ||
)} | ||
/> | ||
</Form> | ||
)} | ||
/> | ||
</div> | ||
); | ||
}; | ||
``` | ||
|
||
#### `withFormik()` | ||
|
||
```tsx | ||
import React from 'react'; | ||
import * as Yup from 'yup'; | ||
import { withFormik, FormikProps, FormikErrors, Form, Field } from 'formik'; | ||
|
||
// Shape of form values | ||
interface FormValues { | ||
email: string; | ||
password: string; | ||
} | ||
|
||
interface OtherProps { | ||
message: string; | ||
} | ||
|
||
// Aside: You may see InjectedFormikProps<OtherProps, FormValues> instead of what comes below in older code.. InjectedFormikProps was artifact of when Formik only exported a HoC. It is also less flexible as it MUST wrap all props (it passes them through). | ||
const InnerForm = (props: OtherProps & FormikProps<FormValues>) => { | ||
const { touched, errors, isSubmitting, message } = props; | ||
return ( | ||
<Form> | ||
<h1>{message}</h1> | ||
<Field type="email" name="email" /> | ||
{touched.email && errors.email && <div>{errors.email}</div>} | ||
|
||
<Field type="password" name="password" /> | ||
{touched.password && errors.password && <div>{errors.password}</div>} | ||
|
||
<button type="submit" disabled={isSubmitting}> | ||
Submit | ||
</button> | ||
</Form> | ||
); | ||
}; | ||
|
||
// The type of props MyForm receives | ||
interface MyFormProps { | ||
initialEmail?: string; | ||
message: string; // if this passed all the way through you might do this or make a union type | ||
} | ||
|
||
// Wrap our form with the withFormik HoC | ||
const MyForm = withFormik<MyFormProps, FormValues>({ | ||
// Transform outer props into form values | ||
mapPropsToValues: props => { | ||
return { | ||
email: props.initialEmail || '', | ||
password: '', | ||
}; | ||
}, | ||
|
||
// Add a custom validation function (this can be async too!) | ||
validate: (values: FormValues) => { | ||
let errors: FormikErrors = {}; | ||
if (!values.email) { | ||
errors.email = 'Required'; | ||
} else if (!isValidEmail(values.email)) { | ||
errors.email = 'Invalid email address'; | ||
} | ||
return errors; | ||
}, | ||
|
||
handleSubmit: values => { | ||
// do submitting things | ||
}, | ||
})(InnerForm); | ||
|
||
// Use <MyForm /> wherevs | ||
const Basic = () => ( | ||
<div> | ||
<h1>My App</h1> | ||
<p>This can be anywhere in your application</p> | ||
<MyForm message="Sign up" /> | ||
</div> | ||
); | ||
|
||
export default Basic; | ||
``` |
Oops, something went wrong.
af0c7d0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to following URLs: