react-i18next: Error after upgrading: "Invariant Violation: Hooks can only be called inside the body of a function component."

Describe the bug Invariant Violation: Hooks can only be called inside the body of a function component.

This error occurs for me after upgrading to the newest version of react-i18next. I’m using SSR for my app but this is occurring in the client-side rendering portion, so I don’t think it’s SSR specific. I compared my code against the razzle-ssr code and it’s effectively the same, the only difference is my App.jsx is a class and not a function. (I tried changing my App to a function and I still got this error).

I am not using Hooks anywhere except for useSSR. I am only using withTranslation (because of decorators)

Occurs in react-i18next version

  • “i18next”: “15.0.4”
  • “i18next-browser-languagedetector”: “3.0.1”
  • “i18next-express-middleware”: “1.7.1”
  • “i18next-node-fs-backend”: “2.1.1”
  • “i18next-xhr-backend”: “2.0.1”
  • “react-i18next”: “10.2.0”

To Reproduce Not sure. Works fine in the Razzle example.

Expected behaviour I should be able to do… anything. My app is broken and I’m not sure why.

Screenshots If applicable, add screenshots or a GIF to help explain your problem. image

image

OS (please complete the following information):

  • Device: MacBook Pro (Retina, 15-inch, Mid 2015)
  • Browser: Chrome Version 72.0.3626.109 (Official Build) (64-bit)

Additional context

config:

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import XHR from 'i18next-xhr-backend';
import LanguageDetector from 'i18next-browser-languagedetector';

const options = {
  allLanguages: ['en'],
  fallbackLng: 'en',
  load: 'languageOnly',

  ns: [
    'about',
  ],
  defaultNS: 'translations',

  saveMissing: false,
  debug: false,


  interpolation: {
    escapeValue: false // not needed for react!!
  },
  wait: process && !process.release
};

// for browser use xhr backend to load translations and browser lng detector
if (process && !process.release) {
  i18n
    .use(XHR)
    // .use(Cache)
    .use(LanguageDetector);
}

i18n.use(initReactI18next);

// initialize if not already initialized
if (!i18n.isInitialized) {
  i18n.init(options);
}

export default i18n;

src/index.js (for client side) – not all of the code but the relevant stuff.


const BaseApp = () => {
  useSSR(window.initialI18nStore, window.initialLanguage);
  return (
    <MobxProvider {...stores}>
      <BrowserRouter>
        <App
          isClientSideRendered={!window.IS_SSR}
          show404Page={window.show404Page || false}
          show500Page={window.show500Page || false}
          userData={window.userData}
        />
      </BrowserRouter>
    </MobxProvider>
  );
};


// It is important to keep the following in sync with `server/app.js`.

ReactDOM.hydrate(
  <BaseApp />,
  document.getElementById('root')
);

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 21 (9 by maintainers)

Most upvoted comments

I have solved this. The problem is that upstream bundles react and react-dom. Discussed here: https://reactjs.org/warnings/invalid-hook-call-warning.html. (#3)

So, it appears that my specific error is unrelated to react-i18next

Adding this to the upstream webpack bundler is the fix:

  externals: {
    // Don't bundle react or react-dom
    react: {
      commonjs: "react",
      commonjs2: "react",
      amd: "React",
      root: "React"
    },
    "react-dom": {
      commonjs: "react-dom",
      commonjs2: "react-dom",
      amd: "ReactDOM",
      root: "ReactDOM"
    }
  },

react and react-dom up-to-date >= 16.8.0

If you like this module don’t forget to star this repo. Make a tweet, share the word or have a look at our https://locize.com to support the devs of this project -> there are many ways to help this project 🙏

@jamuhl thank you for your assistance, same to you @christopher-johnson .

I tried changing hydrate to render, same error. (also removed the SSR stuff when I changed it to render). I think I might know the issue but I’ll double check and come back.