使用 Trans 组件(或替代方案)来实现我的目标以便异步加载翻译句子的一部分的正确方法是什么?
我认为这可能有用:
"use client";
import { Suspense } from "react";
import { Trans } from "react-i18next"; // https://react.i18next.com/latest/trans-component
const mockedFetch = (delay: number) => {
return new Promise<string>((resolve) => {
setTimeout(() => {
const last4DigitsOfCard = "3423";
resolve(last4DigitsOfCard);
}, delay);
});
};
function PersonalizedNumber() {
// TODO: Delete all the mocking. Replace with real backend calls.
const delay = 2_000;
// We are throwing a promise here so that Suspense can catch it and show the loader:
const sentencePromise = mockedFetch(delay);
// `Suspense` will handle this as a loading state automatically:
return sentencePromise;
}
function Loading() {
return <div>Loading...</div>;
}
function Last4DigitsOfCard() {
return (
<Suspense fallback={<Loading />}>
<PersonalizedNumber />
</Suspense>
);
}
export function YourPrepaidCardEndingInLastFour({
locale,
}: {
locale: string;
}) {
return (
<Trans
locale={locale}
i18nKey="yourPrepaidCardIsReady"
components={{
last4DigitsOfCard: <Last4DigitsOfCard />,
}}
/>
);
}
翻译键:
"yourPrepaidCardIsReady": "Your prepaid card ending in <last4DigitsOfCard/> is active and ready to use."
但我明白:
Unhandled Runtime Error
Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.
这似乎有效。
"use client";
import { useEffect, useState } from "react";
import { Trans } from "react-i18next"; // https://react.i18next.com/latest/trans-component
// TODO: Delete all the mocking. Replace with real backend calls.
const delay = 2_000;
const sampleLast4DigitsOfCard = "3423";
const mockedFetch = (delayMs: number) => {
return new Promise<string>((resolve) => {
setTimeout(() => {
resolve(sampleLast4DigitsOfCard);
}, delayMs);
});
};
function Loading() {
return (
<span style={{ border: "1px solid black", padding: "2px" }}>
Loading...
</span>
);
}
function Last4DigitsOfCardSimple() {
return sampleLast4DigitsOfCard;
}
function Last4DigitsOfCardAsync() {
const [value, setValue] = useState<string | null>(null);
useEffect(() => {
async function main() {
const lastFourDigits = await mockedFetch(delay);
setValue(lastFourDigits);
}
main();
}, []);
return value ?? <Loading />;
}
export function YourPrepaidCardEndingInLastFour({
locale,
}: {
locale: string;
}) {
return (
<div>
<div>
Async:{" "}
<Trans
locale={locale}
i18nKey="yourPrepaidCardIsReady"
components={{
last4DigitsOfCard: <Last4DigitsOfCardAsync />,
}}
/>
</div>
<br />
<br />
<div>
Simple (sync):{" "}
<Trans
locale={locale}
i18nKey="yourPrepaidCardIsReady"
components={{
last4DigitsOfCard: <Last4DigitsOfCardSimple />,
}}
/>
</div>
</div>
);
}
但它使用
useEffect
而不是 Suspense
。
我很想知道如何使用
Suspense
来做到这一点。