From a851d305e2bf053f00c0492dfe8a1f8d347a4861 Mon Sep 17 00:00:00 2001
From: Jesse Martin <1626240+jessemartin@users.noreply.github.com>
Date: Mon, 1 Apr 2024 19:19:51 +0000
Subject: [PATCH] fix: stabilize t in app directory
---
__tests__/useTranslation.test.js | 30 +++++++++++++++++++++++++++++-
src/useTranslation.tsx | 22 +++++++++++++++-------
2 files changed, 44 insertions(+), 8 deletions(-)
diff --git a/__tests__/useTranslation.test.js b/__tests__/useTranslation.test.js
index adcd3ac..e19e093 100644
--- a/__tests__/useTranslation.test.js
+++ b/__tests__/useTranslation.test.js
@@ -1,4 +1,4 @@
-import React, { useState } from 'react'
+import React, { useEffect, useState } from 'react'
import { render, cleanup, fireEvent } from '@testing-library/react'
import I18nProvider from '../src/I18nProvider'
import useTranslation from '../src/useTranslation'
@@ -1549,5 +1549,33 @@ describe('useTranslation', () => {
const { container } = render()
expect(container.textContent).toContain(expected)
})
+
+ test('`t` is stable', () => {
+ const Inner = ({ effect }) => {
+ const { t } = useTranslation()
+
+ useEffect(() => {
+ const text = t('ns:interpolation', {
+ count: 3,
+ })
+ effect(text)
+ }, [effect, t])
+ }
+
+ globalThis.__NEXT_TRANSLATE__ = {
+ namespaces: {
+ ns: {
+ interpolation: 'There are {{count}} cats.',
+ },
+ },
+ lang: 'en',
+ config: {},
+ }
+
+ const effect = jest.fn()
+ const { rerender } = render()
+ rerender()
+ expect(effect).toBeCalledTimes(1)
+ })
})
})
diff --git a/src/useTranslation.tsx b/src/useTranslation.tsx
index bd1cbba..2a8b4f8 100644
--- a/src/useTranslation.tsx
+++ b/src/useTranslation.tsx
@@ -15,18 +15,26 @@ function useTranslationInPages(defaultNS?: string): I18n {
)
}
+function isServer() {
+ return typeof window === 'undefined'
+}
+
function useTranslationAppDir(defaultNS?: string) {
const { lang, namespaces, config } = globalThis.__NEXT_TRANSLATE__ ?? {}
const localesToIgnore = config.localesToIgnore || ['default']
const ignoreLang = localesToIgnore.includes(lang)
- const t = transCore({
- config,
- allNamespaces: namespaces,
- pluralRules: new Intl.PluralRules(ignoreLang ? undefined : lang),
- lang,
- })
+ const getT = () => {
+ const t = transCore({
+ config,
+ allNamespaces: namespaces,
+ pluralRules: new Intl.PluralRules(ignoreLang ? undefined : lang),
+ lang,
+ })
- return { t: wrapTWithDefaultNs(t, defaultNS), lang }
+ return wrapTWithDefaultNs(t, defaultNS)
+ }
+ const t = isServer() ? getT() : useMemo(getT, [defaultNS])
+ return { t, lang }
}
export default function useTranslation(defaultNS?: string): I18n {