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 {