Home > Mobile >  How to translate formik ErrorMessage with React i18next
How to translate formik ErrorMessage with React i18next

Time:06-06

I have following components:

import { Formik, Form, useField, ErrorMessage } from "formik";
import * as Yup from "yup";
import Select from "react-select";

const iceCreamOptions = [
  { value: "chocolate", label: "Chocolate" },
  { value: "strawberry", label: "Strawberry" },
  { value: "vanilla", label: "Vanilla" }
];

const FormSelect = ({ name, options }) => {
  const [field, meta, helpers] = useField(name);
  return (
    <>
      <Select
        name={name}
        value={field.value}
        onChange={(value) => helpers.setValue(value)}
        options={options}
        onBlur={() => helpers.setTouched(true)}
      />
      <ErrorMessage name={name} />
    </>
  );
};

const initialValues = {
  icecream: null
};

const validationSchema = Yup.object().shape({
  icecream: Yup.object()
    .shape({
      value: Yup.string(),
      label: Yup.string()
    })
    .required("Please select a value")
    .nullable()
});

export default function App() {
  return (
    <Formik
      initialValues={initialValues}
      onSubmit={(values) => console.log(values)}
      validationSchema={validationSchema}
    >
      {(props) => {
        return (
          <Form>
            <FormSelect name="icecream" options={iceCreamOptions} />
          </Form>
        );
      }}
    </Formik>
  );
}

Now I would like to add tranlations to my application, so i will use React i18next. Basic example is something like that:

const { t } = useTranslation();

<p>{t('message')}</p>

Now, How can i use this translations with my ErrorMessage component? I am sure, I can't do something like that :D

t(<ErrorMessage name={name} />)

So if there is no way to handle it with t and ErrorMessage, I think I need to do following thing:

{meta.touched && meta.error ? (
  <div className="error">{t(meta.error)}</div>
) : null}

CodePudding user response:

I think you can directly translate the validationSchema like this;

const validationSchema = (t) => Yup.object().shape({
  icecream: Yup.object()
    .shape({
      value: Yup.string(),
      label: Yup.string()
    })
    .required(t("RequiredValueTranslation"))
    .nullable()
});

and use it

const [t] = useTranslation()
const schema = () => validationSchema(t)

CodePudding user response:

Another approach would be to use the render function from formik, but in the same way you would have to change the yup message to be the translation key.

ErrorMessage-render

const validationSchema = Yup.object().shape({
  icecream: Yup.object()
    .shape({
      value: Yup.string(),
      label: Yup.string()
    })
    .required("requiredTranslationKey")
    .nullable()
});

and then, in the component body

<ErrorMessage name={name} render={key => t(key)} />

  • Related