React-i18next: How to update translations outside components when executing changeLanguage

Created on 24 Apr 2019  路  2Comments  路  Source: i18next/react-i18next

How to update translations outside of components when executing changeLanguage

I have a small module that exports a array with diffrent translations:

// module.js
import { t } from 'i18next'

export const translations = [
  { text: t('translation_one'), value: '1', key: '1' },
  { text: t('translation_two'), value: '2', key: '2' },
  { text: t('translation_three'), value: '3', key: '3' },
]

I use this array in diffrent components like this:

// Foo.js
import React from 'react'
import { withTranslation } from 'react-i18next'
import { Component } from 'component-library'

import { translations } from 'module'

class Foo extends React.Component {
  render() {
    const { t } = this.props

    return (
      <div>
        {/* translations will not change language*/}
        <Component attribute={translations} />

        <p>{t('this_string_will_change_language')}</p>
      </div>
    )
  }
}

export default withTranslation()(Foo)

The problem I'm experiencing is that when I'm executing the randomMethod below:

// languagePicker.js
import i18nInstance from 'util/i18n' // my i18n setup-file

...
    const randomMethod = (event, target) =>  i18nInstance.changeLanguage(target.value)
...

... the translations made in module.js will not update from(for instance) English to Spanish.
Though {t('this_string_will_change_language')} will update just fine in Foo.js.

Any ideas? What am I doing wrong?

Most helpful comment

any call to t returns a string so setting { text: t('translation_one'), ... will be a string that has no way to update itself (it is typeof string)...

a component wrapped withTranslations triggers a rerender on languageChanged -> inside render t gets called again -> so it's not the string rendered that updates magically but the HOC with triggers a new render.

So either only access translations during rendering or recalculate your array on a bound event: https://www.i18next.com/overview/api#onlanguagechanged

All 2 comments

any call to t returns a string so setting { text: t('translation_one'), ... will be a string that has no way to update itself (it is typeof string)...

a component wrapped withTranslations triggers a rerender on languageChanged -> inside render t gets called again -> so it's not the string rendered that updates magically but the HOC with triggers a new render.

So either only access translations during rendering or recalculate your array on a bound event: https://www.i18next.com/overview/api#onlanguagechanged

Thanks for explanation @jamuhl! It worked like a charm with:

i18next.on('languageChanged', language => {
    ...
})
Was this page helpful?
0 / 5 - 0 ratings