Search code examples
react-nativereduxi18nextreact-i18nextredux-persist

I18Next - wait for Redux store to be set with local data


I would like for i18next to wait for the redux store to be ready. I'm storing the user's chosen language in the store, using persistor from redux-persist to rehydrate it at app startup. I tried to set the language from the store :

// ...
import store from '../redux';
// ...
const lng = store.getState().user.language
  ? store.getState().user.language
  : Localization.locale.slice(0, 2);

i18next
  // .use(languageDetector)
  .use(initReactI18next)
  .init({
    fallbackLng: 'en',
    debug: true,
    resources,
    lng,
  });

But at this point the store is still in its initialState and not rehydrated yet. Is there a way I could do this?


Solution

  • So the PersistGate can implement an onBeforeLift method, waiting for it to be resolved before lifting the "loading" state.

    const onBeforeLift = async () => {
      await initI18Next();
    };
    
    export default function App(): React.ReactElement {
      return (
        <Provider store={store}>
          <PersistGate
            loading={<SplashScreen />}
            persistor={persistor}
            onBeforeLift={onBeforeLift}
          >
            <StatusBar hidden />
            <MainNavigation />
          </PersistGate>
        </Provider>
      );
    }
    

    And in i18n.ts:

    const resources = {
      en: { translation: en },
      fr: { translation: fr },
      he: { translation: he },
    };
    
    export const init = () => {
      const lng = store.getState().user.language
        ? store.getState().user.language
        : Localization.locale.slice(0, 2);
    
      return (
        i18next
          .use(initReactI18next)
          .init({
            fallbackLng: 'en',
            debug: true,
            resources,
            lng,
          })
      );
    };
    
    export default i18next;