🐙

formikのonChangeとは別に動作を実行したいとき

2021/09/23に公開

formikを使ったフォームで、
onChangeのときに、formikで管理された値の更新をしつつ、
別の処理も動かしたい場合の書き方を調べた。

formikとは

Webアプリケーション開発時、入力UIとしてフォームを使用するが、
このフォームに関連する処理を簡潔に行うことができるようにするライブラリ。

Formikのドキュメント にチュートリアルがあるので、
ここの CodeSandbox をいじりながら進めていくとわかりやすい。

単純にonChangeを書いた場合

formikを使ったフォームの場合、
onChange の動作は formik が管理している値の変更処理として動くので、
単純に onChange とかくと、自分で定義した動作で上書きされて、
値の更新処理が動かなくなる。

  return (
    <div>
      <Formik
        initialValues={{ firstName: 'hoge' }}
        onSubmit={ values => {
          alert(JSON.stringify(values, null, 2))
        }}
      >
        {formik => (
          <form onSubmit={formik.handleSubmit}>
            // console.log は動作するが、
	    // firstNameの値が変更されないのでUI上は初期表示のテキストのまま変わらない
            <Field name="firstName" onChange={e => console.log(e.target.value)} />
            <button type="submit">Submit</button>
          </form>
      )}
      </Formik>
    </div>
  )

Dependent Fields のサンプル

フォームAとフォームBの値によって、フォームCの値が変わる、
という他のフォームに依存した場合のサンプルは ここ にあった。

useEffect で依存する変数の変更があったタイミングで、
setFieldValue を使い、自身の値を更新するサンプルになっていた。

いちおう、useEffect を経由しない方法も調べておく。

onChange のときに setFieldValue で値を更新

フォームのonChangeのタイミングで、
自身の値を更新しつつ、他の処理も実行する場合は、
setFieldValue を使えばい良いらしい。

formikで管理された値を setFieldValue で更新することで、
UI上も値が更新され(入力が反映され)、
後続処理として console.log を書いていれば、ログも出力された。

  return (
    <div>
      <Formik
        initialValues={{ firstName: 'hoge' }}
        onSubmit={ values => {
          alert(JSON.stringify(values, null, 2))
        }}
      >
        {formik => (
          <form onSubmit={formik.handleSubmit}>
            <Field name="firstName" onChange={e => {
	      // 自身の値を更新
              formik.setFieldValue("firstName", e.target.value)
              // 他の処理を実行
	      console.log(`firstName の onChange の処理 - ${e.target.value}`)
            }} />
            <button type="submit">Submit</button>
          </form>
      )}
      </Formik>
    </div>
  )

Discussion