react-i18next 16.1.5 → 16.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/amd/react-i18next.js +169 -77
- package/dist/amd/react-i18next.min.js +1 -1
- package/dist/commonjs/useTranslation.js +76 -74
- package/dist/es/package.json +1 -1
- package/dist/es/useTranslation.js +77 -75
- package/dist/umd/react-i18next.js +169 -77
- package/dist/umd/react-i18next.min.js +1 -1
- package/icu.macro.js +3 -0
- package/package.json +4 -3
- package/react-i18next.js +169 -77
- package/react-i18next.min.js +1 -1
- package/src/useTranslation.js +91 -126
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
### 16.2.0
|
|
2
|
+
|
|
3
|
+
- try to address: useTranslation hook violates React's rules of hooks by conditionally calling inner hooks [1863](https://github.com/i18next/react-i18next/issues/1863)
|
|
4
|
+
|
|
5
|
+
### 16.1.6
|
|
6
|
+
|
|
7
|
+
- fix: fix: handle spread props for inner components in Trans (icu) [1877](https://github.com/i18next/react-i18next/pull/1877)
|
|
8
|
+
|
|
1
9
|
### 16.1.5
|
|
2
10
|
|
|
3
11
|
- fix: Incosistent behaviour of Trans and t. Trans set defaultValue when t call doesn't set the field. [1876](https://github.com/i18next/react-i18next/issues/1876)
|
|
@@ -471,7 +471,12 @@ define(['exports', 'react'], (function (exports, React) { 'use strict';
|
|
|
471
471
|
};
|
|
472
472
|
if (key == null) return false;
|
|
473
473
|
const resolved = this.resolve(key, opt);
|
|
474
|
-
|
|
474
|
+
if (resolved?.res === undefined) return false;
|
|
475
|
+
const isObject = shouldHandleAsObject(resolved.res);
|
|
476
|
+
if (opt.returnObjects === false && isObject) {
|
|
477
|
+
return false;
|
|
478
|
+
}
|
|
479
|
+
return true;
|
|
475
480
|
}
|
|
476
481
|
extractFromKey(key, opt) {
|
|
477
482
|
let nsSeparator = opt.nsSeparator !== undefined ? opt.nsSeparator : this.options.nsSeparator;
|
|
@@ -3266,15 +3271,102 @@ define(['exports', 'react'], (function (exports, React) { 'use strict';
|
|
|
3266
3271
|
}
|
|
3267
3272
|
IcuTrans.displayName = 'IcuTrans';
|
|
3268
3273
|
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3274
|
+
var shim = {exports: {}};
|
|
3275
|
+
|
|
3276
|
+
var useSyncExternalStoreShim_development = {};
|
|
3277
|
+
|
|
3278
|
+
/**
|
|
3279
|
+
* @license React
|
|
3280
|
+
* use-sync-external-store-shim.development.js
|
|
3281
|
+
*
|
|
3282
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3283
|
+
*
|
|
3284
|
+
* This source code is licensed under the MIT license found in the
|
|
3285
|
+
* LICENSE file in the root directory of this source tree.
|
|
3286
|
+
*/
|
|
3287
|
+
|
|
3288
|
+
(function () {
|
|
3289
|
+
function is(x, y) {
|
|
3290
|
+
return x === y && (0 !== x || 1 / x === 1 / y) || x !== x && y !== y;
|
|
3291
|
+
}
|
|
3292
|
+
function useSyncExternalStore$2(subscribe, getSnapshot) {
|
|
3293
|
+
didWarnOld18Alpha || void 0 === React$1.startTransition || (didWarnOld18Alpha = true, console.error("You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."));
|
|
3294
|
+
var value = getSnapshot();
|
|
3295
|
+
if (!didWarnUncachedGetSnapshot) {
|
|
3296
|
+
var cachedValue = getSnapshot();
|
|
3297
|
+
objectIs(value, cachedValue) || (console.error("The result of getSnapshot should be cached to avoid an infinite loop"), didWarnUncachedGetSnapshot = true);
|
|
3298
|
+
}
|
|
3299
|
+
cachedValue = useState({
|
|
3300
|
+
inst: {
|
|
3301
|
+
value: value,
|
|
3302
|
+
getSnapshot: getSnapshot
|
|
3303
|
+
}
|
|
3304
|
+
});
|
|
3305
|
+
var inst = cachedValue[0].inst,
|
|
3306
|
+
forceUpdate = cachedValue[1];
|
|
3307
|
+
useLayoutEffect(function () {
|
|
3308
|
+
inst.value = value;
|
|
3309
|
+
inst.getSnapshot = getSnapshot;
|
|
3310
|
+
checkIfSnapshotChanged(inst) && forceUpdate({
|
|
3311
|
+
inst: inst
|
|
3312
|
+
});
|
|
3313
|
+
}, [subscribe, value, getSnapshot]);
|
|
3314
|
+
useEffect(function () {
|
|
3315
|
+
checkIfSnapshotChanged(inst) && forceUpdate({
|
|
3316
|
+
inst: inst
|
|
3317
|
+
});
|
|
3318
|
+
return subscribe(function () {
|
|
3319
|
+
checkIfSnapshotChanged(inst) && forceUpdate({
|
|
3320
|
+
inst: inst
|
|
3321
|
+
});
|
|
3322
|
+
});
|
|
3323
|
+
}, [subscribe]);
|
|
3324
|
+
useDebugValue(value);
|
|
3325
|
+
return value;
|
|
3326
|
+
}
|
|
3327
|
+
function checkIfSnapshotChanged(inst) {
|
|
3328
|
+
var latestGetSnapshot = inst.getSnapshot;
|
|
3329
|
+
inst = inst.value;
|
|
3330
|
+
try {
|
|
3331
|
+
var nextValue = latestGetSnapshot();
|
|
3332
|
+
return !objectIs(inst, nextValue);
|
|
3333
|
+
} catch (error) {
|
|
3334
|
+
return true;
|
|
3335
|
+
}
|
|
3336
|
+
}
|
|
3337
|
+
function useSyncExternalStore$1(subscribe, getSnapshot) {
|
|
3338
|
+
return getSnapshot();
|
|
3339
|
+
}
|
|
3340
|
+
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
|
|
3341
|
+
var React$1 = React,
|
|
3342
|
+
objectIs = "function" === typeof Object.is ? Object.is : is,
|
|
3343
|
+
useState = React$1.useState,
|
|
3344
|
+
useEffect = React$1.useEffect,
|
|
3345
|
+
useLayoutEffect = React$1.useLayoutEffect,
|
|
3346
|
+
useDebugValue = React$1.useDebugValue,
|
|
3347
|
+
didWarnOld18Alpha = false,
|
|
3348
|
+
didWarnUncachedGetSnapshot = false,
|
|
3349
|
+
shim = "undefined" === typeof window || "undefined" === typeof window.document || "undefined" === typeof window.document.createElement ? useSyncExternalStore$1 : useSyncExternalStore$2;
|
|
3350
|
+
useSyncExternalStoreShim_development.useSyncExternalStore = void 0 !== React$1.useSyncExternalStore ? React$1.useSyncExternalStore : shim;
|
|
3351
|
+
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
|
|
3352
|
+
})();
|
|
3353
|
+
|
|
3354
|
+
{
|
|
3355
|
+
shim.exports = useSyncExternalStoreShim_development;
|
|
3356
|
+
}
|
|
3357
|
+
|
|
3358
|
+
var shimExports = shim.exports;
|
|
3359
|
+
|
|
3360
|
+
const notReadyT = (k, optsOrDefaultValue) => {
|
|
3361
|
+
if (isString(optsOrDefaultValue)) return optsOrDefaultValue;
|
|
3362
|
+
if (isObject(optsOrDefaultValue) && isString(optsOrDefaultValue.defaultValue)) return optsOrDefaultValue.defaultValue;
|
|
3363
|
+
return Array.isArray(k) ? k[k.length - 1] : k;
|
|
3364
|
+
};
|
|
3365
|
+
const notReadySnapshot = {
|
|
3366
|
+
t: notReadyT,
|
|
3367
|
+
ready: false
|
|
3275
3368
|
};
|
|
3276
|
-
const
|
|
3277
|
-
const useMemoizedT = (i18n, language, namespace, keyPrefix) => React.useCallback(alwaysNewT(i18n, language, namespace, keyPrefix), [i18n, language, namespace, keyPrefix]);
|
|
3369
|
+
const dummySubscribe = () => () => {};
|
|
3278
3370
|
const useTranslation = (ns, props = {}) => {
|
|
3279
3371
|
const {
|
|
3280
3372
|
i18n: i18nFromProps
|
|
@@ -3287,88 +3379,88 @@ define(['exports', 'react'], (function (exports, React) { 'use strict';
|
|
|
3287
3379
|
if (i18n && !i18n.reportNamespaces) i18n.reportNamespaces = new ReportNamespaces();
|
|
3288
3380
|
if (!i18n) {
|
|
3289
3381
|
warnOnce(i18n, 'NO_I18NEXT_INSTANCE', 'useTranslation: You will need to pass in an i18next instance by using initReactI18next');
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
if (isObject(optsOrDefaultValue) && isString(optsOrDefaultValue.defaultValue)) return optsOrDefaultValue.defaultValue;
|
|
3293
|
-
return Array.isArray(k) ? k[k.length - 1] : k;
|
|
3294
|
-
};
|
|
3295
|
-
const retNotReady = [notReadyT, {}, false];
|
|
3296
|
-
retNotReady.t = notReadyT;
|
|
3297
|
-
retNotReady.i18n = {};
|
|
3298
|
-
retNotReady.ready = false;
|
|
3299
|
-
return retNotReady;
|
|
3300
|
-
}
|
|
3301
|
-
if (i18n.options.react?.wait) warnOnce(i18n, 'DEPRECATED_OPTION', 'useTranslation: It seems you are still using the old wait option, you may migrate to the new useSuspense behaviour.');
|
|
3302
|
-
const i18nOptions = {
|
|
3382
|
+
}
|
|
3383
|
+
const i18nOptions = React.useMemo(() => ({
|
|
3303
3384
|
...getDefaults(),
|
|
3304
|
-
...i18n
|
|
3385
|
+
...i18n?.options?.react,
|
|
3305
3386
|
...props
|
|
3306
|
-
};
|
|
3387
|
+
}), [i18n, props]);
|
|
3307
3388
|
const {
|
|
3308
3389
|
useSuspense,
|
|
3309
3390
|
keyPrefix
|
|
3310
3391
|
} = i18nOptions;
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
const
|
|
3317
|
-
|
|
3318
|
-
const [t, setT] = React.useState(getT);
|
|
3319
|
-
let joinedNS = namespaces.join();
|
|
3320
|
-
if (props.lng) joinedNS = `${props.lng}${joinedNS}`;
|
|
3321
|
-
const previousJoinedNS = usePrevious(joinedNS);
|
|
3322
|
-
const isMounted = React.useRef(true);
|
|
3323
|
-
React.useEffect(() => {
|
|
3392
|
+
const namespaces = React.useMemo(() => {
|
|
3393
|
+
const nsOrContext = ns || defaultNSFromContext || i18n?.options?.defaultNS;
|
|
3394
|
+
return isString(nsOrContext) ? [nsOrContext] : nsOrContext || ['translation'];
|
|
3395
|
+
}, [ns, defaultNSFromContext, i18n]);
|
|
3396
|
+
i18n?.reportNamespaces?.addUsedNamespaces?.(namespaces);
|
|
3397
|
+
const subscribe = React.useCallback(callback => {
|
|
3398
|
+
if (!i18n) return dummySubscribe;
|
|
3324
3399
|
const {
|
|
3325
3400
|
bindI18n,
|
|
3326
3401
|
bindI18nStore
|
|
3327
3402
|
} = i18nOptions;
|
|
3328
|
-
|
|
3329
|
-
if (
|
|
3330
|
-
if (props.lng) {
|
|
3331
|
-
loadLanguages(i18n, props.lng, namespaces, () => {
|
|
3332
|
-
if (isMounted.current) setT(getNewT);
|
|
3333
|
-
});
|
|
3334
|
-
} else {
|
|
3335
|
-
loadNamespaces(i18n, namespaces, () => {
|
|
3336
|
-
if (isMounted.current) setT(getNewT);
|
|
3337
|
-
});
|
|
3338
|
-
}
|
|
3339
|
-
}
|
|
3340
|
-
if (ready && previousJoinedNS && previousJoinedNS !== joinedNS && isMounted.current) {
|
|
3341
|
-
setT(getNewT);
|
|
3342
|
-
}
|
|
3343
|
-
const boundReset = () => {
|
|
3344
|
-
if (isMounted.current) setT(getNewT);
|
|
3345
|
-
};
|
|
3346
|
-
if (bindI18n) i18n?.on(bindI18n, boundReset);
|
|
3347
|
-
if (bindI18nStore) i18n?.store.on(bindI18nStore, boundReset);
|
|
3403
|
+
if (bindI18n) i18n.on(bindI18n, callback);
|
|
3404
|
+
if (bindI18nStore) i18n.store.on(bindI18nStore, callback);
|
|
3348
3405
|
return () => {
|
|
3349
|
-
|
|
3350
|
-
if (
|
|
3351
|
-
|
|
3406
|
+
if (bindI18n) bindI18n.split(' ').forEach(e => i18n.off(e, callback));
|
|
3407
|
+
if (bindI18nStore) bindI18nStore.split(' ').forEach(e => i18n.store.off(e, callback));
|
|
3408
|
+
};
|
|
3409
|
+
}, [i18n, i18nOptions]);
|
|
3410
|
+
const snapshotRef = React.useRef();
|
|
3411
|
+
const getSnapshot = React.useCallback(() => {
|
|
3412
|
+
if (!i18n) {
|
|
3413
|
+
return notReadySnapshot;
|
|
3414
|
+
}
|
|
3415
|
+
const calculatedReady = !!(i18n.isInitialized || i18n.initializedStoreOnce) && namespaces.every(n => hasLoadedNamespace(n, i18n, i18nOptions));
|
|
3416
|
+
const calculatedT = i18n.getFixedT(props.lng || i18n.language, i18nOptions.nsMode === 'fallback' ? namespaces : namespaces[0], keyPrefix);
|
|
3417
|
+
const lastSnapshot = snapshotRef.current;
|
|
3418
|
+
if (lastSnapshot && lastSnapshot.ready === calculatedReady && lastSnapshot.lng === (props.lng || i18n.language) && lastSnapshot.keyPrefix === keyPrefix) {
|
|
3419
|
+
return lastSnapshot;
|
|
3420
|
+
}
|
|
3421
|
+
const newSnapshot = {
|
|
3422
|
+
t: calculatedT,
|
|
3423
|
+
ready: calculatedReady,
|
|
3424
|
+
lng: props.lng || i18n.language,
|
|
3425
|
+
keyPrefix
|
|
3352
3426
|
};
|
|
3353
|
-
|
|
3427
|
+
snapshotRef.current = newSnapshot;
|
|
3428
|
+
return newSnapshot;
|
|
3429
|
+
}, [i18n, namespaces, keyPrefix, i18nOptions, props.lng]);
|
|
3430
|
+
const [loadCount, setLoadCount] = React.useState(0);
|
|
3431
|
+
const {
|
|
3432
|
+
t,
|
|
3433
|
+
ready
|
|
3434
|
+
} = shimExports.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
3354
3435
|
React.useEffect(() => {
|
|
3355
|
-
if (
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
ret.ready = ready;
|
|
3363
|
-
if (ready) return ret;
|
|
3364
|
-
if (!ready && !useSuspense) return ret;
|
|
3365
|
-
throw new Promise(resolve => {
|
|
3366
|
-
if (props.lng) {
|
|
3367
|
-
loadLanguages(i18n, props.lng, namespaces, () => resolve());
|
|
3368
|
-
} else {
|
|
3369
|
-
loadNamespaces(i18n, namespaces, () => resolve());
|
|
3436
|
+
if (i18n && !ready && !useSuspense) {
|
|
3437
|
+
const onLoaded = () => setLoadCount(c => c + 1);
|
|
3438
|
+
if (props.lng) {
|
|
3439
|
+
loadLanguages(i18n, props.lng, namespaces, onLoaded);
|
|
3440
|
+
} else {
|
|
3441
|
+
loadNamespaces(i18n, namespaces, onLoaded);
|
|
3442
|
+
}
|
|
3370
3443
|
}
|
|
3371
|
-
});
|
|
3444
|
+
}, [i18n, props.lng, namespaces, ready, useSuspense, loadCount]);
|
|
3445
|
+
const finalI18n = i18n || {};
|
|
3446
|
+
const ret = React.useMemo(() => {
|
|
3447
|
+
const arr = [t, finalI18n, ready];
|
|
3448
|
+
arr.t = t;
|
|
3449
|
+
arr.i18n = finalI18n;
|
|
3450
|
+
arr.ready = ready;
|
|
3451
|
+
return arr;
|
|
3452
|
+
}, [t, finalI18n, ready]);
|
|
3453
|
+
if (i18n && useSuspense && !ready) {
|
|
3454
|
+
throw new Promise(resolve => {
|
|
3455
|
+
const onLoaded = () => resolve();
|
|
3456
|
+
if (props.lng) {
|
|
3457
|
+
loadLanguages(i18n, props.lng, namespaces, onLoaded);
|
|
3458
|
+
} else {
|
|
3459
|
+
loadNamespaces(i18n, namespaces, onLoaded);
|
|
3460
|
+
}
|
|
3461
|
+
});
|
|
3462
|
+
}
|
|
3463
|
+
return ret;
|
|
3372
3464
|
};
|
|
3373
3465
|
|
|
3374
3466
|
const withTranslation = (ns, options = {}) => function Extend(WrappedComponent) {
|