Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
yoruvo opened this issue May 27, 2020 · 2 comments
Open

Comments

@yoruvo
Copy link

yoruvo commented May 27, 2020

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?

@jannikbuschke
Copy link
Owner

jannikbuschke commented May 27, 2020

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

@ryall
Copy link

ryall commented Jun 29, 2020

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants