• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

i18next / react-i18next / 19516272328
98%

Build:
DEFAULT BRANCH: master
Ran 19 Nov 2025 09:01PM UTC
Jobs 1
Files 22
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

19 Nov 2025 09:01PM UTC coverage: 97.425% (-0.001%) from 97.426%
19516272328

push

github

web-flow
fix runaway effect in useTranslation (#1889)

In the useTranslation.js hook, the loadNamespaces function itself is asynchronous (it fetches translations). The mechanism that triggers the state update (and thus the re-render) is the callback provided to loadNamespaces.

  Here is the relevant code block from useTranslation.js:

        // ...
        const [loadCount, setLoadCount] = useState(0); // <--- 1. State hook
        // ...

        useEffect(() => {
          if (i18n && !ready && !useSuspense) {
            const onLoaded = () => setLoadCount((c) => c + 1); // <--- 2. Callback updating state
            if (props.lng) {
              loadLanguages(i18n, props.lng, namespaces, onLoaded);
            } else {
              loadNamespaces(i18n, namespaces, onLoaded); // <--- 3. Trigger
            }
          }
        }, [i18n, props.lng, namespaces, ready, useSuspense, loadCount]); // <--- 4. Dependency array

  The Cycle of Runaway Effect:

   1. Render: useTranslation(['ns1']) is called. A new array ['ns1'] is created.
   2. Memoization (Broken): namespaces is memoized with useMemo, but it depends on ns. Since ns is a new reference, namespaces becomes a new reference.
   3. Effect: The useEffect has namespaces in its dependency array. React sees it changed, so it runs the effect.
   4. Logic: Inside the effect, if !ready (translations not loaded yet), it calls loadNamespaces.
   5. Callback: It passes onLoaded, which calls setLoadCount(c => c + 1).
   6. Update: loadNamespaces might finish immediately (if cached) or later. It calls onLoaded.
   7. Re-render: setLoadCount triggers a re-render of the component.
   8. Loop: Back to Step 1. The component re-renders, creates a new ['ns1'] array, namespaces changes, effect runs again, state updates again... Infinite Loop.

  By stabilizing namespaces, the namespaces reference remains the same across renders even if ns is a new array object. Therefore, useEffect sees no change in dependencies and ... (continued)

643 of 699 branches covered (91.99%)

3 of 3 new or added lines in 1 file covered. (100.0%)

2762 of 2835 relevant lines covered (97.43%)

61.79 hits per line

Jobs
ID Job ID Ran Files Coverage
1 19516272328.1 19 Nov 2025 09:01PM UTC 22
97.43
GitHub Action Run
Source Files on build 19516272328
  • Tree
  • List 22
  • Changed 1
  • Source Changed 1
  • Coverage Changed 1
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Repo
  • Github Actions Build #19516272328
  • 7ffba1c4 on github
  • Prev Build on master (#19492775938)
  • Next Build on master (#19516332699)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc