jannikbuschke / formik-antd

Simple declarative bindings for Ant Design and Formik.

Home Page:https://codesandbox.io/s/github/jannikbuschke/formik-antd-example

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Run a function over errors in Form.Item / validationSchema? (Yup, i18next)

yoruvo opened this issue · comments

Hi,

my setup for forms is:

  • formik and formik-antd for the form creation
  • Yup for validation
  • react-i18next for localization

This setup works quite well for labels, placeholders etc. but I'm struggling with errors.

If I design my validation schema for Formik like so:

import * as Yup from "yup"
import { useTranslation } from "react-i18next"

const { t } = useTranslation()

  const validationSchema = Yup.object().shape({
    name: Yup.string().required(t("form.validation.required")),
  })

then the validation is translated correctly, but the translation does not change when switching languages in i18next.

A solution suggested in many other issues I've read about the topic (from the different projects) is to use the i18next t() function in the React output instead. However, for me, this is being handled by formik-antd's Form.Item class.

However, I cannot see any option to pass that t() function to the Form.Item error output without overriding the Form.Item.

Could you advise on how to proceed?

You might be able to place the schema and the calls to the t function inside a component. To not reintantiate the schema on every render you probabaly want to wrap it in a React.useMemo call.
The memo need to be re-evaluated on every language change. I guess the react-i18next exposes somewhere the current language value in a hook. This value you would need to pass to the memo as a dependency.

So something along these lines:

function MyComponent() {
  const { t, lang } = useTranslation(); // not sure how to get lang, it might be somewhere else
  const schema = React.useMemo(()=> {
     return /* Yup.object().shape.... with t() calls*/, 
       , [lang]); // <-- dependency for useMemo, so that on every change of `lang` the schema gets re-created
  return <Formik ....
}

I agree this would be useful and the solution suggested isn't possible in my case because my validation schema does not return translated messages but rather a serialized object to generate the translated message. I do this because my API needs to be language agnostic, and some form errors are generated there.

I was solving this before using Antd with a custom ErrorMessage component, but with Antd, the error is internal to the FormItem.