Skip to content

Commit

Permalink
Update versions in docs
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredpalmer committed Nov 21, 2019
1 parent d0d7602 commit af0c7d0
Show file tree
Hide file tree
Showing 5 changed files with 1,473 additions and 0 deletions.
110 changes: 110 additions & 0 deletions website/versioned_docs/version-2.0.4/api/useField.md
@@ -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 website/versioned_docs/version-2.0.4/guides/typescript.md
@@ -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;
```

1 comment on commit af0c7d0

@vercel
Copy link

@vercel vercel bot commented on af0c7d0 Nov 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.