type:any

【TSならすぐわかるけど】Formikをつかってinputパーツを使うとき、{...formik.getFieldProps('hoge')}にonBlurが上書きされていたのでメモ

{ category: "Front-end" }

JS環境(非TSの意)でしかハマらない話ですが、Formikを扱うInputコンポーネントを使っていてonBlurが発火しないというバグに見舞われていました。結論としては、InputコンポーネントでonBlur等を渡す{...props}のあとに{...formik.getFieldProps('hoge')}があったためでした。

formik.getFieldPropsは以下の型の値を返します。

参考:https://github.com/jaredpalmer/formik/blob/ec89b3a7d1665fb4b086ffaee8cbd11b4f2ab986/packages/formik/src/types.tsx#L312

/** Field input value, name, and event handlers */
export interface FieldInputProps {
  /** 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'];
}

という風に、型が指定されているのでTS環境ならすぐonBlurが上書きされていることがわかります。VSCodeの静的解析でもこのように出ます。

'onBlur' が複数回指定されているため、ここでの使用は上書きされます。ts(2783)
App.tsx(42, 50): このスプレッドは、常にこのプロパティを上書きします。

{...props}と{...formik.getFieldProps('hoge')}の位置入れ替えの影響範囲が大きいので限定的に位置を入れ替えたコンポーネントを作って使って解決しました。。最初からここは考慮しておいたほうがいいですね。

いまやっているReact案件の環境がJSなためずっとハマっていたので、メモ記事でした。