How do I use react-i18next with a connected component How do I use react-i18next with a connected component reactjs reactjs

How do I use react-i18next with a connected component


In our project, we successfully utilize this:

import { compose } from 'redux';import { withNamespaces } from 'react-i18next';import { connect } from 'react-redux';...export default compose(withNamespaces('translation'), connect(mapStateToProps))(ComponentName);

With this, we connect to Redux with mapStateToProps and we have translations.


I am using SSR with RazzleJS and in my case its working perfectly fine. I connected my connect and withTranslation like this:

export default connect(mapStateToProps,mapDispatchToProps)(withTranslation()(Component));


I'm actually having trouble to determine in which order you wrap your components in HOCs. In the project I'm currently working in we wrap like withNamespaces(connect(withStyles(component))), which works really well (withNamespaces is essentially the same as withTranslations). We had issues when trying to connect a translated component, you are possibly experiencing the same issues right now. So here's our way of doing it:

You have a "normal" component like

type InjectedProps = StateProps & ExternalProps & MyComponentsTranslationsexport class MyComponent extends React.Component<InjectedProps> {    ...} 

(Note: the procedure works exactly the same with functional components)

you can const MyConnectedComponent = connect(mapStateToProps, mapDispatchToProps)(MyComponent)

and finally, you do a

import {WithNamespaces, withNamespaces} from "react-i18next"export const LocalizedMyComponent = withNamespaces()(  ({t,...rest}): WithNamepsaces) => (    <MyConnectedComponent translations={{ put translations here }} {...rest} />  ))

Now, the trick is that we define an interface MyComponentsTranslations {} where we put all the required translations or translate functions (in case of plurals).MyComponentsTranslations is added to the InjectedProps to make them available in the original component.

You can always simply inject the t-function of i18n into your components, but in my current project we decided that it is much cleaner to

  • explicitly name the translations required for the component
  • Since neither the original component nor the connected component are dependant on the t-function they are quiet easy to test

Let me know if this works for you.

Also, to make the whole thing a little bit more elegant, you can use these helpers:

export interface Translations<T> {  translations: T}export const createTranslations = <T>(translations: T): Translations<T> => ({  translations,})

This allows you to set

type InjectedProps = StateProps & Translations<MyComponentTranslations>

and in the withNamespace hoc:

<MyConnectedComponent {...createTranslations<MyComponentTranslations>({ put translations here })} {...rest} />