Skip to content

Commit cd2816a

Browse files
authored
fix: ensure render of I18nProvider in async scenarios (#839)
1 parent 664955e commit cd2816a

1 file changed

Lines changed: 21 additions & 4 deletions

File tree

packages/react/src/I18nProvider.tsx

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,23 +74,40 @@ export const I18nProvider: FunctionComponent<I18nProviderProps> = ({
7474
i18n,
7575
defaultComponent,
7676
})
77+
const getRenderKey = () => {
78+
return (forceRenderOnLocaleChange ? (i18n.locale || 'default') : 'default') as string
79+
}
7780

78-
const [context, setContext] = React.useState<I18nContext>(makeContext())
81+
const [context, setContext] = React.useState<I18nContext>(makeContext()),
82+
[renderKey, setRenderKey] = React.useState<string>(getRenderKey())
7983

8084
/**
8185
* Subscribe for locale/message changes
8286
*
8387
* I18n object from `@lingui/core` is the single source of truth for all i18n related
8488
* data (active locale, catalogs). When new messages are loaded or locale is changed
8589
* we need to trigger re-rendering of LinguiContext.Consumers.
90+
*
91+
* We call `setContext(makeContext())` after adding the observer in case the `change`
92+
* event would already have fired between the inital renderKey calculation and the
93+
* `useEffect` hook being called. This can happen if locales are loaded/activated
94+
* async.
8695
*/
8796
React.useEffect(() => {
88-
const unsubscribe = i18n.on("change", () => setContext(makeContext()))
97+
const unsubscribe = i18n.on("change", () => {
98+
setContext(makeContext())
99+
setRenderKey(getRenderKey())
100+
})
101+
if (renderKey === 'default') {
102+
setRenderKey(getRenderKey())
103+
}
104+
if (forceRenderOnLocaleChange && renderKey === 'default') {
105+
console.log("I18nProvider did not render. A call to i18n.activate still needs to happen or forceRenderOnLocaleChange must be set to false.")
106+
}
89107
return () => unsubscribe()
90108
}, [])
91109

92-
const renderKey = forceRenderOnLocaleChange && i18n.locale
93-
if (forceRenderOnLocaleChange && !renderKey) return null
110+
if (forceRenderOnLocaleChange && renderKey === 'default') return null
94111

95112
return (
96113
<LinguiContext.Provider value={context} key={renderKey}>

0 commit comments

Comments
 (0)