nomolog

プロダクトマネジメント、技術、ビジネス、ときどきライフハック

April 10, 2021

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>
}

ポイントは以下

  • ユーザ認証失敗したときのメッセージを表示する用のvalueを用意する
    • 例では general とした
  • onSubmit内でのsubmit処理で、失敗したら actions.setErrorField で1で用意したvalueに値を詰める
  • errors.general に値が入っていたらエラーを表示する
    • {errors.general && エラーメッセージ} のような形

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


気に入ったら、以下からシェアやフォローいただけると嬉しいです!