ttag-org / ttag

:orange_book: simple approach for javascript localization
https://ttag.js.org/
MIT License
345 stars 43 forks source link

How to pass current language through react context? #145

Closed dimaqq closed 5 years ago

dimaqq commented 5 years ago

In a SPA, I'd like to detect user language at runtime, also I'm loading translations asynchronously.

Thus I'd like to be able to pass Config or conf or perhaps just the selected language around.

I wish there was an example how to do that.

My current hack works half-way -- new component is drawn in selected language, but existing component is not re-drawn. Then again IANAE. 😄

AlexMost commented 5 years ago

Hi @dimaqq! Not sure, that I have got your point. Have you looked through this example - https://github.com/ttag-org/CRA-runtime-example?

dimaqq commented 5 years ago

This may very well be exactly what I had in mind, thank you!

dimaqq commented 5 years ago

Here's the summary for CRA-runtime-example:

This is pretty neat and ought to work for the most common case -- if someone changes the language, it's because they don't understand current language 🙄

What I wanted was a bit different — to change locale on the fly, keeping the rest of state and props intact, e.g. partially filled forms. I'm also loading locale data asynchronously, which may be a folly, as translations are needed to display almost anything, thus they are needed early. If I can make my hack elegant, I'll share the details here 🤔

AlexMost commented 5 years ago

@dimaqq glad that it worked for you)

If you don't want to package locale data in the main bundle, you can download it asynchronously via some kind of async chunk(in the webpack terms), but that would require the app to wait until the locale chunk will be downloaded.

I think it is possible to change locale on the fly, but this task is a little bit tricky because you should trigger rerender somehow. I will really appreciate if you will share your experience!

dimaqq commented 5 years ago

I've set it up this way:

<LOCALE_CONTEXT.Provider value={this.set_locale.bind(this)}>

set_locale calls ttag useLocale and updates select language in component state.

Then the language selection widget uses context and sets locale; and react notices that the outer component state changes and redraws. IANAE and cannot tell whether react redraws all descendants when outer component state changes or if it tracks state of this in the bound method in the context provider. Either way it works :)

Initial language is set up null and when translations are loaded (async), same set_locale is called which triggers a redraw.

AlexMost commented 5 years ago

@dimaqq thanks a lot for the research! Will try that, and also would be great to have a doc for this kind of setup!