LoginSignup
2
0

More than 5 years have passed since last update.

Formik: 全てのフィールドが再描写されないようにする

Last updated at Posted at 2019-01-16

シナリオ

以下のようにして、FormikFieldに自作のコンポーネントCustomFieldを指定する場合。

import { Field, Form, FormikProps } from 'formik'
import * as React from 'react'

interface IFormValue {
    custom: string
}

const CustomForm = React.memo<FormikProps<IFormValue>>(props => (
    <Formik>
        <Form>
            <Field
                name="custom"
                component={CustomField}
                setFieldValue={props.setFieldValue}
            />
        </Form>
    </Formik>
))

問題点

Formik (〜1.4.1)にはsetFieldValue()を呼び出してフィールドの値をセットすると、<Formik></Formik>内の全てのフィールドが再描写されてしまう問題があるようです。入力の度に全てのフィールドが再描写されないようにするには以下のようにstate管理をする必要があります。

1. stateprops.field.valueで初期化する。

interface ICustomFieldProps {
    setFieldValue: (name: string, value: string) => void
}

interface ICustomFieldState {
    value: string
}

class CustomField extends React.Component<ICustomFieldProps, ICustomFieldState> {
    public state: ICustomFieldState = { value: this.props.field.value }
    ...
}

2. onChangeではstate.valueのみを更新する。

private handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    this.setState({
        value: event.currentTarget.value
    })
}

3. onBlurprops.field.valueを更新する。

private handleBlur = (event: React.ChangeEvent<HTMLInputElement>) => {
    this.props.setFieldValue(
        this.props.field.name,
        event.currentTarget.value
    )
}

4. shouldComponentUpdateprops.field.valueとstate.valueを比較して値が異なる場合のみtrueを返す。

public shouldComponentUpdate(
    nextProps: IFieldProps,
    nextState: IFieldState
) {
    return nextProps.field.value !== nextState.value
}

参照

How to avoid rerendering?

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0