v1.x から v2.x への移行

破壊的な変更

最小要件

  • Formik 2 は React Hooks の上に構築されているため、React 16.8.x 以上である必要があります。
  • Formik 2 は unknown 型を使用しているため、TypeScript 3.0 以上である必要があります (TypeScript を使用している場合)。

Formik 2.x にはいくつかの破壊的な変更があります。幸いなことに、これらは多くの人に影響を与えないでしょう。

resetForm

Formik 2 では、より多くの初期状態のための新しい props、initialErrorsinitialTouchedinitialStatus を導入しました。したがって、resetForm のシグネチャが変更されました。フォームの次の初期値のみをオプションで受け入れるのではなく、Formik の部分的な次の初期状態をオプションで受け入れるようになりました。

v1

// Reset to `initialValues`
formik.resetForm();
// Reset form and set the next `initialValues` of the form
formik.resetForm({ name: '', email: '' });

v2

// Reset the form. This will set the next initial state of
// Formik to the `initialValues`, `initialErrors`, `initialTouched`,
// `initialStatus` props.
formik.resetForm();
// Reset the form back to `initialXXXX` but change next
// `initialValues` to a custom value
formik.resetForm({
values: { name: 'Custom initial values', email: '' },
});
// Reset form back to `initialXXXX`, but change next `initialValues`
// and `initialErrors` of the form
formik.resetForm({
values: { name: '', email: '' },
errors: { name: 'Something special' },
});
// Reset form back to `initialXXXX`, but change next `initialStatus` to 'Foo'
formik.resetForm({
status: 'Foo',
});

setError

このメソッドは、v1.x リリースで警告付きでしばらくの間非推奨でした。v2 で完全に削除されました。代わりに Formik の setStatus(status) を使用してください。同じように機能します。注: これは、依然として存在する setErrors (複数形) ではありません。

validate

ご存知かもしれませんが、validate からバリデーションエラーの Promise を返すことができます。1.x では、この Promise が解決されたか拒否されたかは関係ありませんでした。どちらの場合も、Promise のペイロードはバリデーションエラーとして解釈されました。2.x では、拒否は実際のエラーとして解釈され、フォームのエラー状態は更新されません。エラーの拒否された Promise を返すバリデーション関数は、代わりにエラーの解決された Promise を返すように調整する必要があります。

ref

現在、ref prop を使用して Formik に ref をアタッチすることはできません。ただし、prop innerRef を使用して、この問題を回避できます。React.forwardRef を代わりに使用するための WIP #2208 があります。

isValid

このプロパティは、dirty の値を考慮しなくなりました。つまり、フォームが dirty でない場合 (つまり、最初のレンダリング時や値が変更されていない場合) に送信ボタンを無効にしたい場合は、明示的に確認する必要があります。

<button disabled={!isValid || !dirty} type="submit">
Submit
</button>

Typescript の変更

FormikActions

FormikActionsFormikHelpers に名前が変更されました。 型をインポートまたはエイリアスするのは簡単な変更です。

v1

import { FormikActions } from 'formik';

v2

import { FormikHelpers as FormikActions } from 'formik';

FieldProps

FieldProps は 2 つのジェネリック型パラメータを受け入れるようになりました。両方のパラメータはオプションですが、FormValues は最初のパラメータから 2 番目のパラメータに移動しました。

v1

type Props = FieldProps<FormValues>;

v2

type Props = FieldProps<FieldValue, FormValues>;

新機能

チェックボックスと複数選択

Angular、Vue、または Svelte と同様に、Formik 2 は、組み込みの配列バインディングとブール値の動作を使用して React チェックボックスと複数選択を「修正」します。これは、Formik 1.x で人々が最も混乱していたことの 1 つでした。

import React from 'react';
import { Formik, Field, Form } from 'formik';
import { Debug } from './Debug';
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
const CheckboxExample = () => (
<div>
<h1>Checkboxes</h1>
<p>
This example demonstrates how to properly create checkboxes with Formik.
</p>
<Formik
initialValues={{
isAwesome: false,
terms: false,
newsletter: false,
jobType: ['designer'],
location: [],
}}
onSubmit={async values => {
await sleep(1000);
alert(JSON.stringify(values, null, 2));
}}
>
{({ isSubmitting, getFieldProps, handleChange, handleBlur, values }) => (
<Form>
{/*
This first checkbox will result in a boolean value being stored.
*/}
<div className="label">Basic Info</div>
<label>
<Field type="checkbox" name="isAwesome" />
Are you awesome?
</label>
{/*
Multiple checkboxes with the same name attribute, but different
value attributes will be considered a "checkbox group". Formik will automagically
bind the checked values to a single array for your benefit. All the add and remove
logic will be taken care of for you.
*/}
<div className="label">
What best describes you? (check all that apply)
</div>
<label>
<Field type="checkbox" name="jobType" value="designer" />
Designer
</label>
<label>
<Field type="checkbox" name="jobType" value="developer" />
Developer
</label>
<label>
<Field type="checkbox" name="jobType" value="product" />
Product Manager
</label>
{/*
You do not _need_ to use <Field>/useField to get this behavior,
using handleChange, handleBlur, and values works as well.
*/}
<label>
<input
type="checkbox"
name="jobType"
value="founder"
checked={values.jobType.includes('founder')}
onChange={handleChange}
onBlur={handleBlur}
/>
CEO / Founder
</label>
{/*
The <select> element will also behave the same way if
you pass `multiple` prop to it.
*/}
<label htmlFor="location">Where do you work?</label>
<Field
component="select"
id="location"
name="location"
multiple={true}
>
<option value="NY">New York</option>
<option value="SF">San Francisco</option>
<option value="CH">Chicago</option>
<option value="OTHER">Other</option>
</Field>
<label>
<Field type="checkbox" name="terms" />I accept the terms and
conditions.
</label>
{/* Here's how you can use a checkbox to show / hide another field */}
{!!values.terms ? (
<div>
<label>
<Field type="checkbox" name="newsletter" />
Send me the newsletter <em style={{ color: 'rebeccapurple' }}>
(This is only shown if terms = true)
</em>
</label>
</div>
) : null}
<button type="submit" disabled={isSubmitting}>
Submit
</button>
<Debug />
</Form>
)}
</Formik>
</div>
);
export default CheckboxExample;

useField()

まさにあなたが考えているように、これは <Field> のようですが、フックを使用しています。使用法についてはドキュメントを参照してください。

useFormikContext()

connect() と同等のフックです。

<Field as>

<Field/>as という prop を受け入れるようになりました。これは、onChangeonBlurvalue などをコンポーネントまたは文字列に直接注入します。これは、Emotion または Styled コンポーネントを使用している人が、ラップされた関数で component の render props をクリーンアップする必要がなくなった場合に役立ちます。

// <input className="form-input" placeholder="Jane" />
<Field name="firstName" className="form-input" placeholder="Jane" />
// <textarea className="form-textarea"/></textarea>
<Field name="message" as="textarea" className="form-textarea"/>
// <select className="my-select"/>
<Field name="colors" as="select" className="my-select">
<option value="red">Red</option>
<option value="green">Green</option>
<option value="blue">Blue</option>
</Field>
// with styled-components/emotion
const MyStyledInput = styled.input`
padding: .5em;
border: 1px solid #eee;
/* ... */
`
const MyStyledTextarea = MyStyledInput.withComponent('textarea');
// <input className="czx_123" placeholder="google.com" />
<Field name="website" as={MyStyledInput} placeholder="google.com"/>
// <textarea placeholder="Post a message..." rows={5}></textarea>
<Field name="message" as={MyStyledTextArea} placeholder="Post a message.." rows={4}/>

getFieldProps(nameOrProps)

FormikPropsgetFieldProps、および getFieldMeta には 2 つの便利な追加機能があります。これらは、プロップドリリングが大好きである場合、コンテキストベースの API を使用していない場合、またはカスタム useField を構築している場合に役立つ Kent C. Dodds スタイルのプロップゲッターです。

export interface FieldInputProps<Value> {
/** Value of the field */
value: Value;
/** Name of the field */
name: string;
/** Multiple select? */
multiple?: boolean;
/** Is the field checked? */
checked?: boolean;
/** Change event handler */
onChange: FormikHandlers['handleChange'];
/** Blur event handler */
onBlur: FormikHandlers['handleBlur'];
}

getFieldMeta(name)

名前が与えられると、オブジェクトが返されます

export interface FieldMetaProps<Value> {
/** Value of the field */
value: Value;
/** Error message of the field */
error?: string;
/** Has the field been visited? */
touched: boolean;
/** Initial value of the field */
initialValue?: Value;
/** Initial touched state of the field */
initialTouched: boolean;
/** Initial error message of the field */
initialError?: string;
}

その他

  • FormikContext がエクスポートされるようになりました
  • validateOnMount?: boolean = false
  • initialErrorsinitialTouchedinitialStatus が追加されました

非推奨の警告

すべての render props は、コンソール警告付きで非推奨になりました。

<Field><FastField><Formik><FieldArray> では、render prop は、将来のバージョンで削除されるため、警告付きで非推奨になりました。代わりに、子コールバック関数を使用してください。この非推奨は、React Context Consumer の使用法と並行することを意図しています。

- <Field name="firstName" render={props => ....} />
+ <Field name="firstName">{props => ... }</Field>
このページは役に立ちましたか?

ニュースレターに登録する

Formik の最新ニュース、記事、リソースをあなたの受信箱に送信します。

Copyright © 2020 Formium, Inc. All rights reserved.