react-i18next: useTranslation breaking "Rules of Hooks"

Describe the bug We’re using the new useTranslation hook in our components. However, during development React complains that some hooks have been rendered conditionally and that the amount of hooks in a component has changed. When switching back to the Translation HOCs the error disappeared, so I assume it’s because of this line here:

https://github.com/i18next/react-i18next/blob/ece439751c09b0cbe8170f07bfe79617ce589cb8/src/useTranslation.js#L14

Conditionally rendering hooks break the “Rules of Hooks”, so this should be refactored to always render all hooks.

Our component does not render any hooks conditionally, I have checked thrice.

Occurs in react-i18next version 10.0.5

Expected behaviour No error to occur and no hooks rendering conditionally.

Screenshots image

OS (please complete the following information):

  • Device: MBP 2015, Latest MacOS
  • Browser: Chrome 72.0.3626.96

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 40 (17 by maintainers)

Most upvoted comments

published in react-i18next@10.1.0

you can set:

i18next.init({
  // ...
  react: {
    useSuspense: false
  }
});

// in components
const { t, i18n, ready } = useTranslation();

AAAAAGH. Found it!

It never had anything to do with the provider or the .use(...).

The actual reason is: we’re using the useTranslation-hook twice / not as the last hook in the “hook stack” of our component.

However, as you know, the hook sometimes throws a promise (when the translations haven’t loaded yet), causing the subsequent hooks (in our component) to not be rendered. When it doesn’t throw on subsequent invocations, the hooks after the useTranslation-hook will be rendered causing the issue.

Please remove this behavior. This will cause more interference in the future, when more people start using the hook with lazy-loaded translations.

would be possible…but guess it does not hurt - might be there are other cases where users prefer not using suspense yet (existing codebase)