React+Formikのvalidationで[Uncaught (in promise)]というエラーが出る際の対応


いつの頃からかValidationでエラーの際に、ChromeのConsoleに、

![スクリーンショット 2019-12-11 5.36.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/6e572117-8c07-ab3d-08f1-9fd710cdd719.png "スクリーンショット 2019-12-11 5.36.25.png")

というようなエラーが表示されるようになっていた。
エラーは本当の意味でのエラーではなく、"正常に"バリデーションが効いた際に表示されているようだ。

>古いサンプルを動かしたら出ないのでバージョンの問題か？。原因は不明。


## エラーが表示されるコード（いままで）

render={}としている以外は本家のサンプルと変わらない。

>render=()使っても出ます。

```jsx
import React from 'react';
import './App.css';

import { Formik } from 'formik';
import * as Yup from 'yup';

class App extends React.Component {
  render() {
    return (
      <div style={{padding:30}}>
        <Formik
          initialValues={{ name: '' }}
          onSubmit={(values) => alert(JSON.stringify(values))}
          validationSchema={Yup.object().shape({
            name: Yup.string().required(),
          })}
        >
          {
            ({ handleSubmit, handleChange, handleBlur, values, errors, touched, setErrors }) => (
              <form onSubmit={handleSubmit}>
                <input
                  type="text"
                  name="name"
                  id="name"
                  value={values.name}
                  onChange={handleChange}
                  onBlur={handleBlur}
                />
                <div style={{color:'red'}}>
                  {errors.name}
                </div>
                <div>
                  <button type="submit">submit</button>
                </div>
              </form>
            )
          }
        </Formik>
      </div>
    );
  }
}

export default App;
```

このコードを実行してValidationを効かせると、

![スクリーンショット 2019-12-11 5.49.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/03410176-de7d-f1ba-c042-e6f133cdab40.png "スクリーンショット 2019-12-11 5.49.00.png")

という感じになる。。。
ほっといてもいいが、気持ち悪いので対応を考えました。


## 改善（案）


エラーメッセージ自体は「Promiseのrejectがcatchされてないぞ！」というものなので、catchするようにすればよい。
が、どこでcatchすればいいのだろう・・・と試行錯誤し、とりあえず下記のようにしました。

要点は、

* formのonSubmit={handleSubmit}をやめる
* submitボタンが押されたときにsubmitForm()を実行し、そこでエラーをcatch
* いちおうsetErrorsでerrorをerrorsに反映（これはやらなくても動く）

という感じ。
handleSubmitをオーバーライドしてもいい気がしたが、一旦対応とする。

```diff
import React from 'react';
import './App.css';

import { Formik } from 'formik';
import * as Yup from 'yup';

class App extends React.Component {
  render() {
    return (
      <div style={{ padding: 30 }}>
        <Formik
          initialValues={{ name: '' }}
          onSubmit={(values) => alert(JSON.stringify(values))}
          validationSchema={Yup.object().shape({
            name: Yup.string().required(),
          })}
        >
          {
            ({ handleSubmit, handleChange, handleBlur, values, errors, touched, submitForm, setErrors }) => (
+              <form>
                <input
                  type="text"
                  name="name"
                  id="name"
                  value={values.name}
                  onChange={handleChange}
                  onBlur={handleBlur}
                />
                <div style={{ color: 'red' }}>
                  {errors.name}
                </div>
+                <div>
+                  <button type="submit" onClick={(e) => {
+                    e.preventDefault();
+                    submitForm().catch(error => setErrors(error));
+                  }}>submit</button>
+                </div>
              </form>
            )
          }
        </Formik>
      </div>
    );
  }
}

export default App;
```

上記を実行すると、

![スクリーンショット 2019-12-11 5.50.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/3ee7073a-637a-4d9a-70e0-5c2d9db68dbf.png "スクリーンショット 2019-12-11 5.50.04.png")

いちおう何も出ない。

## その他

以前に自分が書いたコードでは出てなかった。その際のFormikのバージョンは2.0.6で、現在は2.0.7なのでバージョンを落としてみたが、だめだった。ブラウザのバージョン差か？と思ったりもしたが、違うみたい・・・。なんだろう。