Paw*_*żyk 4 i18next reactjs react-i18next
我有一个基于 React 的应用程序,并使用 i18next 的 Trans 组件进行翻译。
假设我们有一个用户注册表单,我们想通过显示以下文本来确认已创建新帐户:
名为NAME的用户已创建。
其中NAME由用户提供并以粗体显示。
我现在的反应代码如下:
<Trans i18n={i18next} i18nKey="userCreated" values={{name: 'Tom'}}>
User with name <strong>{{name}}</strong> has been created.
</Trans>
Run Code Online (Sandbox Code Playgroud)
和以下翻译字符串
"userCreated": "User with name <1>{{name}}</1> has been created.",
Run Code Online (Sandbox Code Playgroud)
对于一个简单的情况,name: 'Tom'它工作正常并显示
名为Tom的用户已创建。
不过我想让用户在他们的名字中使用特殊字符。当我改名时Tom&Jerry我得到
Tom&Jerry已创建具有名称的用户。
经过一些研究后,我认为问题在于 i18next 和 React 都转义了它们的输入,因此名称被转义了两次。i18next.init我通过添加以下选项关闭了 i18next 转义
interpolation: {escapeValue: false},
这解决了汤姆和杰瑞的情况:
名为Tom&Jerry 的用户已创建。
但有一些输入完全破坏了它,例如设置name: 'Tom<'像这样的渲染(名称后面的所有内容都是粗体):
名为Tom 的用户已创建。
设置name: '<Tom>'给了我:
已创建具有名称的用户。
(根本没有显示名字)。我希望它像这样渲染:
<Tom>已创建具有名称的用户。
有办法让它发挥作用吗?
这个问题没有优雅的解决方案。问题的根源在于Trans组件的源代码。您要么需要为此文件创建一个补丁来更改此行为,要么自己实现一个作弊技巧。如果您要使用欺骗性的解决方案,您需要创建一个UnescapedTrans使用 lodash 转义 HTML 实体的组件:
import React, { Suspense } from "react";
import { Trans } from "react-i18next";
import { unescape } from "lodash";
const getUnescapeChildrenRef = ref =>
Array.from(ref.childNodes).forEach(node => {
if (!node.innerText) {
return node;
}
node.innerText = unescape(node.innerText);
});
const UnescapedTrans = props => (
<div ref={getUnescapeChildrenRef}>
<Trans {...props} tOptions={{ interpolation: { escapeValue: true } }} />
</div>
);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11135 次 |
| 最近记录: |