1

I upgraded my old project to newer versions like react v17.0.1 and react-i18next v11.8.3.

Now I have a problem: everytime I select a language which hast already been loaded I get the error:

You may not call store.getState() while the reducer is executing. The reducer has already received the state as an argument. Pass it down from the top reducer instead of reading it from the store.

For example: inital language is "EN". When I select a other language and go back to "EN" the error appears. Also the same when I switch for example to ES then to DE then back ES error appears. so it is not a problem with the language itself.

I found this stackoverflow post but I'm not using redux-devtools like in the post.

This is the react-i18next init

i18n.use(Backend)
    .use(LanguageDetector)
    .use(initReactI18next) // pass the i18n instance to react-i18next.
    .init({
        lng: language,
        fallbackLng,
        whitelist: availableLanguages,
        detection: options,
        backend: {
            loadPath: languageUrl,
            crossDomain: true
        },
        interpolation: {
            escapeValue: false
        },
        react: {
            useSuspense: false
        },
    });

So everytime I change to a language the first time it works but the second time it crashes in "i18n.changeLanguage(....)"

import i18n from "i18next";
export default function reducer(state = {
   language: 'en'
}, action) {
switch (action.type) {
    case "CHANGE_LANGUAGE": {
        console.log(action.payload)
        i18n.changeLanguage(action.payload);
        console.log("this will not appear the second time")

        return { ...state, language: action.payload };
    }
    default:
        break;
}

return state;
}
WeSt
  • 889
  • 5
  • 14
  • 32

1 Answers1

0

The problem here is that you are using side effects in the reducer: i18n.changeLanguage(action.payload) has nothing to do there.

You can either listen to the change of language property in the reducer from the React component:

    const languageId = useSelector((state) => state.lang.languageId);
    useEffect(() => {
        i18n.changeLanguage(languageId);
    }, [languageId]);

Or you can use saga for handling the side effects. The latter is recommended.

Ioan Stoianov
  • 105
  • 10