Yup: Use setLocale within a react component to work with language switching

Created on 14 Oct 2018  路  2Comments  路  Source: jquense/yup

I spent some time experimenting with setLocale but unfortunately didn't manage to get it work for my use-case which is to take into account language switching.

To build some context I use Yup with Formik and my react application structure is as follow:

<App>
  <ThemeProvider>
    <LanguageProvider>
      <Page>
        <Form />
      </Page>
    </LanguageProvider>
  </ThemeProvider>
</App>

My <LanguageProvider> React component is responsible for loading the new language strings on initial application load and whenever user switches to a different language; once retrieved the messages are then passed to react-intl's <IntlProvider>.

What I'm trying to achieve is within my <LanguageProvider>, once I have loaded the new locale messages, to call yup's setLocale to override the default messages according to the current locale.

Here is an example of how I'm using setLocale:

import { setLocale } from 'yup'

setLocale({
  mixed: {
    required: 'my required message'
  }
})

And finally an example of my form component:

import { object, string, lazy } from 'yup'
...
const validationSchema = object().shape({
  field1: string().required()
  field2: lazy(value => {
    ...
    return string().required()
  })
})
...
export default withFormik({
  mapPropsToValues,
  validationSchema,
  handleSubmit
})(MyForm);

With this setup currently the override Im trying to apply to the default "required" message doesn't really work because by the time I call setLocale <MyForm> react component has already been loaded and so the imports of yup are already in place.
I tried different approaches and I couldn't come across any way that allows me to successfully invoke setLocale within a React component because of the above reason.

What is interesting is that with my form example above the field2 actually does get the overridden "required" message because is using yup.lazy(), if I change that to use any of the existing yup schemas (like string or number) than the default yup "required" message will be applied and not my override.

The only way I managed to get setLocale to work is by invoking it in a place, and outside of a React component, before any other yup instances are loaded; like in my App.js f.i.
Obviously this is pretty static and wouldn't allow me to achieve what I'm after and so to change the yup messages when switching language.

Do you have any suggestion or are you able to advice if I'm doing anything wrong?

Most helpful comment

Hi there,

any reason why this was closed without comments?

@santino did you manage to dynamically use setLocale?

I'm a bit struggling here unfortunately

thanks

All 2 comments

Hi there,

any reason why this was closed without comments?

@santino did you manage to dynamically use setLocale?

I'm a bit struggling here unfortunately

thanks

@thomasmery you can find the theory there : https://github.com/jaredpalmer/formik/issues/704#issuecomment-400973362
-> give the translationId to yup via setLocale & override ErrorMessage :

<ErrorMessage name={name}>
  {messageId => (
    <p className="help is-danger">
      <FormattedMessage id={messageId} />
    </p>
  )}
</ErrorMessage>

Hope it helps.

Was this page helpful?
0 / 5 - 0 ratings