useTranslation is the cause of the rerender component
See original GitHub issueš Bug Report
I got rerendering issue while use const { t } = useTranslation()
of gatsby-plugin-react-i18next. It is the same with t
API get from useTranslation
of react-i18next
and useI18next of this library.
Iāve confirmed in react-i18next, seems like there is no issue with it.
https://github.com/i18next/react-i18next/issues/1291#issuecomment-813844756 https://github.com/welldone-software/why-did-you-render/issues/187
Could you please give me the idea to prevent a re-rendering issue every time use t
of useTranslation? Thanks šš»
To Reproduce
Repo: https://github.com/zcmgyu/react-i18next-rerender-issue


There is no rerender issue if using react-i18next with create-react-app project.
https://codesandbox.io/s/why-did-you-render-sandbox-forked-891xf?file=/src/index.js
Expected behavior
Could useTranslation
feature without re-render because of the same name of fixedT
Your Environment
- runtime version: Node v15.8.0, browser Chrome
- i18next version: ^20.1.0
- react-i18next: ^11.8.12
- gatsby-plugin-react-i18next: ^1.1.1
- os: MacOS Big Sur
Issue Analytics
- State:
- Created 2 years ago
- Comments:11 (10 by maintainers)
Looks like I misunderstood. I did my
<Trans>
test in plain gatsby. This only happens in Storybook? Maybe thereās something weird going on there. Perhaps thet()
ori18n
is being cached somewhere, making the element not getting updated. But I guess thatās off topic here.Though it does look like this repo is becoming dormant. I guess weād have to build our own npm package for the time being.
Iām running into this issue too. I think I managed to track down why itās rerendering.
During the first render (first call to
wrapPageElement
),i18n.init()
actually doesnāt fully initialize itself because it doesnāt have the translation resources yet. This can be seen here:https://github.com/i18next/i18next/blob/c2eccedbc13295e94b98f14ff85f2bd377d774e0/src/i18next.js#L193-L197
And so the rest of the initialization is deferred and gets done later asynchronously.
So for the rest of the first render,
i18n
remains half-initialized while the rest of the page gets rendered. And all the calls touseTranslation()
notice this, and setup some callbacks to wait fori18n
to fully initialize. So once the resources are loaded, andi18n
actually completely initialized, all the calls touseTranslation()
get updated, which is why all the rerendering is happening.Knowing this, the fix is actually really simple.
Currently, the plugin loads the resources right after
i18n.init()
: https://github.com/microapps/gatsby-plugin-react-i18next/blob/c6dabc14200a68003f7b02f934fa47bacabf539f/src/plugin/wrapPageElement.tsx#L119-L122So all we need to do is build the resources first, and pass it into
i18n.init()
, so that itāll initialize immediately.In my scenario, the profiling result went from this:
to this:
