Pass language as a dynamic property from parent component to all descendants in React

675 views Asked by At

I'm creating multi language app. So I'd like to propagate language property to all descendants. Thus I can ad language prefix to all links and routes in my app I know two ways to do it:

  1. using context, but it is not recommended to use it, because it is experimental.
  2. using redux store but in this case I need to connect every component to store.

So I wish to know which case is more preferable or if none of those, then may be there is another option.

P.S.
3. pass as a property from component to every child all the levels deep, like this:

 <Component1 lang={props.lang} />
   <Component2 lang={props.lang} />
     <Component3 lang={props.lang} />
       <Component4 lang={props.lang} />
         ....
           <Component#N lang={props.lang} />
1

There are 1 answers

0
Marian Gibala On BEST ANSWER

Here are my thoughts and solutions that work the best for me.

  1. Handling internationalization logic is not really the job of the component. Generating links at that level is coupling component too much to the app and makes reuse of them complicated. I have done it in the past and it was a nightmare to maintain. Not even translation related things, think about changing URL for some view when you have generated links to it from different places of your app. I consider it now bad practice and not recommend for anything bigger than TODO app.

Now I'm using separate service which handles dynamically generation of links and routes based on app configuration/internationalization.

That service is exposed as a global in Webpack configuration as let's say LocationPointer. So for example:

LocationPoiner.admin() 

will return string pointing to admin view based on an active language (/en/admin-panel).

  1. I don't treat language as a changeable state. For SEO and UX reasons, what I want is internationalization based on a shareable URL, which is the single source of truth.

If you are on SPA and change language by clicking button etc. then the whole app is forced to completely refresh.

During page loading, I detect language, save its value somewhere and pull correct translations.

Note - My backend is using internationalization as well, so when a user changes the language, some requests have to be done again in order to display correct data. It's not just refreshing front-end components. And is worth to remember about it. When your app grows it will probably also respond with different messages/data depending on internationalization.

My pulled front-end translations are stored in another service and exposed as a global through Webpack as __(), which returns translated string.

So if I want Link in my React component I will do:

<Link to={LocationPointer.admin()}>{__('Admin')}</Link>

Passing language as a prop makes sense to me when you use multiple languages on a single page at the same moment. Otherwise, in my opinion - it just creates a mess.