From 551566412addeafe95bb90c6d59e98ddeb8c1b1b Mon Sep 17 00:00:00 2001 From: Marco Schumacher Date: Fri, 1 Oct 2021 15:37:10 +0200 Subject: [PATCH] feat: render passes hook translator --- src/react/translator.tsx | 36 +++++++++++++++++++----------------- src/react/types.ts | 2 +- src/react/useStore.ts | 11 +++++++++-- test/react.test.tsx | 4 ++-- 4 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/react/translator.tsx b/src/react/translator.tsx index 72635fe..1d50cbc 100644 --- a/src/react/translator.tsx +++ b/src/react/translator.tsx @@ -42,7 +42,7 @@ export function createTranslator(options: ReactCreateTranslatorO const contextLocale = useContext(TranslationContext).locale; const locale = overrideLocale ?? contextLocale ?? sourceLocale; const dicts = useStore(store, locale, ...castArray(fallbackLocale)); - const [sourceDict] = useStore(store, sourceLocale) ?? []; + const [sourceDict] = useStore(store, sourceLocale); return useMemo(() => { const t: TranslatorFn = (id, ...[values, options]) => { @@ -104,7 +104,7 @@ export function createTranslator(options: ReactCreateTranslatorO const contextLocale = useContext(TranslationContext).locale; const locale = options?.locale ?? contextLocale ?? sourceLocale; const dicts = useStore(store, locale, ...castArray(fallbackLocale)); - const [sourceDict] = useStore(store, sourceLocale) ?? []; + const [sourceDict] = useStore(store, sourceLocale); const fallback = options?.fallback ?? defaultFallback; const placeholder = options?.placeholder ?? defaultPlaceholder; @@ -129,10 +129,15 @@ export function createTranslator(options: ReactCreateTranslatorO return ; }; - const RenderComponent = ({ renderFn, dependecies = [renderFn] }: { renderFn: (locale: string) => ReactNode; dependecies?: any[] }) => { - const contextLocale = useContext(TranslationContext).locale; - const locale = contextLocale ?? sourceLocale; - const value = useMemo(() => renderFn(locale), [locale, ...dependecies]); + const RenderComponent = ({ + renderFn, + dependecies = [renderFn], + }: { + renderFn: (t: HookTranslator) => ReactNode; + dependecies?: any[]; + }) => { + const t = useTranslator(); + const value = useMemo(() => renderFn(t), [t, ...dependecies]); return <>{value}; }; @@ -144,46 +149,43 @@ export function createTranslator(options: ReactCreateTranslatorO TranslatorFn, Omit, keyof TranslatorFn> >(createTranslatorComponent, { - locale: render((locale) => locale, []), + locale: render((t) => t.locale, []), unknown: createTranslatorComponent as InlineTranslator['unknown'], format(template, ...[values]) { - return render((locale) => format({ template, values: values as any, locale, cache: store.cache }), [template, hash(values)]); + return render((t) => format({ template, values: values as any, locale: t.locale, cache: store.cache }), [template, hash(values)]); }, render, dateTimeFormat(date, options = dateTimeFormatOptions) { - return render((locale) => store.cache.get(Intl.DateTimeFormat, locale, options).format(toDate(date)), [date, hash(options)]); + return render((t) => store.cache.get(Intl.DateTimeFormat, t.locale, options).format(toDate(date)), [date, hash(options)]); }, displayNames(code, options = displayNamesOptions) { // TODO remove cast when DisplayNames is included in standard lib - return render((locale) => store.cache.get((Intl as any).DisplayNames, locale, options).of(code), [code, hash(options)]); + return render((t) => store.cache.get((Intl as any).DisplayNames, t.locale, options).of(code), [code, hash(options)]); }, listFormat(list, options = listFormatOptions) { // TODO remove cast when DisplayNames is included in standard lib return render( - (locale) => store.cache.get((Intl as any).ListFormat, locale, options).format(list), + (t) => store.cache.get((Intl as any).ListFormat, t.locale, options).format(list), [list && hash([...list]), hash(options)], ); }, numberFormat(number, options = numberFormatOptions) { - return render((locale) => store.cache.get(Intl.NumberFormat, locale, options).format(number), [number, hash(options)]); + return render((t) => store.cache.get(Intl.NumberFormat, t.locale, options).format(number), [number, hash(options)]); }, pluralRules(number, options = pluralRulesOptions) { - return render((locale) => store.cache.get(Intl.PluralRules, locale, options).select(number), [number, hash(options)]); + return render((t) => store.cache.get(Intl.PluralRules, t.locale, options).select(number), [number, hash(options)]); }, relativeTimeFormat(value, unit, options = relativeTimeFormatOptions) { - return render( - (locale) => store.cache.get(Intl.RelativeTimeFormat, locale, options).format(value, unit), - [value, unit, hash(options)], - ); + return render((t) => store.cache.get(Intl.RelativeTimeFormat, t.locale, options).format(value, unit), [value, unit, hash(options)]); }, }); diff --git a/src/react/types.ts b/src/react/types.ts index a3beba1..d7cff3e 100644 --- a/src/react/types.ts +++ b/src/react/types.ts @@ -40,5 +40,5 @@ export interface InlineTranslator extends HookTranslator ReactNode, dependencies?: any[]): ReactNode; + render(renderFn: (t: HookTranslator) => ReactNode, dependencies?: any[]): ReactNode; } diff --git a/src/react/useStore.ts b/src/react/useStore.ts index 56df554..5d0048e 100644 --- a/src/react/useStore.ts +++ b/src/react/useStore.ts @@ -1,6 +1,7 @@ -import { useEffect, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { FlatDict, MaybePromise } from '..'; import { hash } from '../cache'; +import { arrEquals } from '../helpers'; import { Store } from '../store'; export function useStore(store: Store, ...locales: string[]): MaybePromise[] { @@ -12,5 +13,11 @@ export function useStore(store: Store, ...locales: string[]): MaybePromise { return (
setI((i) => i + 1)}> - {t.context.t.render((locale) => { + {t.context.t.render((t) => { renderCount++; - return new Intl.DateTimeFormat(locale, { dateStyle: 'full' }).format(date); + return new Intl.DateTimeFormat(t.locale, { dateStyle: 'full' }).format(date); }, [])} ,