6

I am trying to find best concept of translations for my react app.

I have a higher order component for translations and use it by:

export default translate('MyComponent')(MyComponent);

And inside a component I have all texts available by props - it works fine for me.

But, I have a lot of pure javascript files with constants and also need a tranlations there. There is for example validation schema's with error messages or constats with select elements like:

export default [
    {
        value: 'aaa',
        label: 'bbb', // want to translate this label
    }
];

What is the best aproch to translate pure js files in react app?

marcint339
  • 348
  • 3
  • 11
  • Assuming you're using a global store like Redux/similar, I'd go with dispatching an action there whenever the language changes, and then using that Redux store state to determine what is returned by your locale index. For example, you could create some locale files `en.js, it.js` etc, import those, and then use a switch statement with the Redux store state to determine which locale object to return. – Sam A. Horvath-Hunt Jun 13 '17 at 10:31
  • did you check the react-intl ? – Dhaval Patel Jun 13 '17 at 10:33
  • @DhavalPatel Yes, I checked, but I have no idea how to use it in pure js file using translations from redux store – marcint339 Jun 13 '17 at 10:34
  • @SamHH I do that, but I can't use state in pure js files – marcint339 Jun 13 '17 at 10:36
  • 1
    you can create a stateless component for pure js file and use it – Dhaval Patel Jun 13 '17 at 10:37
  • It's a constants file, so I don't want to do that... – marcint339 Jun 13 '17 at 10:39

3 Answers3

10

looks like you use i18next (translate hoc).

Just import i18next on the file and use t directly:

import i18next from 'i18next';
export default {
    error: {
        value: 'aaa',
        label: i18next.t('yourKey'), // want to translate this label
    }
};

But better would be translating inside the component - so translation can adapt to language change. So i consider doing what Chase suggest would be best option:

export default {
    error: {
        value: 'aaa',
        key: 'bbb', // use it as key for t call
    }
};

component

import Constants from './Constants.js';
const { error } = Constants;

...


render(){
    const { t } = this.props;
    return <span>{${t(error.key)}}</span>
}
jamuhl
  • 4,352
  • 2
  • 25
  • 31
1

I'm not sure how your translation is organized exactly but I had similar situation with constants translation and I found solution that suited me. If you have translation file with key - value translation format you can use it.

So you have constants file like this:

export default [
  {
    id: 1,
    label: 'Cat'
  },
  {
    id: 2,
    label: 'Dog'
  }
]

And have translation for this values:

{
  "Animal.title": {
    "en-uk": "Animals",
    "da-dk": "Dyr"
  },
  "Animal.cat": {
    "en-uk": "Cat",
    "da-dk": "Kat"
  },
  "Animal.dog": {
    "en-uk": "Dog",
    "da-dk": "Hund"
  }
}

And you have HOC that provides you translate method and MyComponent that you need to translate (not sure how it's implemented in your app but I imagine it like this).

import Animals from './constants/animals'

class MyComponent extends React.Component {
  render() {
    const { translate } = this.props
    return (
      <div>
        {translate('Animal.title')}
        {Animals.map(animal => (
           <Animal 
             id={animal.id} 
             name={animal.label} 
           />
        )}
      </div>
    )
  }
}

translate('MyComponent')(MyComponent);

So now we have translated MyComponent but there is a problem - constants from pure js file are not translated. In this case I see only one solution - rewrite constants in this way:

export default [
  {
    id: 1,
    label: 'Animal.cat'
  },
  {
    id: 2,
    label: 'Animal.dog'
  }
]

We replaced labels with translation key, so now we can change out MyComponent to translate labels:

class MyComponent extends React.Component {
  render() {
    const { translate } = this.props
    return (
      <div>
        {translate('Animal.title')}
        {Animals.map(animal => (
           <Animal 
             id={animal.id} 
             name={translate(animal.label)} 
           />
        )}
      </div>
    )
  }
}
Igor S
  • 951
  • 7
  • 19
0

I'm kind of confused on the question, but would something like this work?

Constants.js

export default {
    error: {
        value: 'aaa',
        label: 'bbb', // want to translate this label
    }
};

Then in a component you can destructure it like

import Constants from './Constants.js';
const { error } = Constants;
...
render(){
    return <span>{`Error: ${error.label}`}</span>
}

Assuming there is only one error container like the example you provided.

Chase DeAnda
  • 15,963
  • 3
  • 30
  • 41