Ryusuke Nomoto

FormikでServer Errorに対処する方法

日本語の記事を見かけなかったので備忘録として残します 💁‍♂️

TL;DR

  • setFieldErrorを使いましょう

背景

  • Formikを使ったログインページを作っていた
  • Formik + Yupを使ったバリデーション例は結構ネットで見かけたが、基本はクライアントサイドのバリデーションばかりでユーザ認証などのサーバーサイドバリデーションの例を見かけなかった

ログインフォームでユーザ認証を行う際の例

次のような感じ
import ... const LoginView = () => { return ( <Formik initialValues={{ email: 'sample@sample.com', password: '', general: '', // <- エラーメッセージ表示用にvalueを用意 }} validationSchema={Yup.object().shape({ email: Yup.string().email('Must be a valid email').max(255).required('Email is required'), password: Yup.string().max(255).required('Password is required') })} onSubmit={({email, password}, actions) => { signIn({username: email, password: password}) .then(() => { navigate('/app/dashboard', { replace: true }); // <- 成功したらリダイレクト }) .catch(error => { actions.setFieldError('general', error.message); // <- 失敗したらエラーをセット }) .finally(() => { actions.setSubmitting(false); }) }} > {({ errors, handleBluer, handleChange, handleSubmit isSubmitting, touched, values }) => ( <form onSubmit={handleSubmit}> {errors.general && <Alert>メールアドレスまたはパスワードが正しくありません</Alert>} <TextField label='email' ... /> <TextField label='password' ... /> <Button ... /> Sign in </Button> }
ポイントは以下
  1. ユーザ認証失敗したときのメッセージを表示する用のvalueを用意する
      • 例では general とした
  1. onSubmit内でのsubmit処理で、失敗したら actions.setErrorField で1で用意したvalueに値を詰める
  1. errors.general に値が入っていたらエラーを表示する
      • {errors.general && エラーメッセージ} のような形
       

以上、Formikを使ったサーバーサイドエラーのハンドリングでした 💁‍♂️
badge