我有一个navigation
,其中包含标准项目,例如:联系方式,服务,价格等...我将其呈现为:
const menuItemList = menuItems.map((item, index) => {
return (
<li key={index}>
<NavLink to={item.url}>{item.title}</NavLink>
</li>
);
});
工作正常。但是现在我需要翻译此导航,为此我使用了react-intl
库。根据{{1}} doc,我必须像这样使用react-intl
:
FormattedMessage
有效。但是如何将其用于列表呈现?我认为它可以解决此问题,但是不行。
<p>
<FormattedMessage id="mainText"/>
</p>
伙计们,请帮忙。如何使用const menuItemsList = menuItems.map((item, index) => {
return (
<li key={index}>
<NavLink to={item.url}>
<FormattedMessage id="mainText" values={item.title}/>
</NavLink>
</li>
);
});
中的React
用FormattedMessage
中的项目呈现列表?
答案 0 :(得分:0)
您需要将消息传递给intl。例如:
{
profile: 'Profile',
settings: 'Settings'
}
我想你也有
const menuItems = [
{
url: '/profile',
title: 'profile'
},
{
url: '/settings',
title: 'settings'
}
]
因此您可以像这样使用它
const menuItemsList = menuItems.map((item, index) => {
return (
<li key={index}>
<NavLink to={item.url}>
<FormattedMessage id={item.title} />
</NavLink>
</li>
);
});
答案 1 :(得分:0)
您可以使用defineMessages
const menuItemsList = menuItems.map((item, index) => {
return (
<li key={index}>
<NavLink to={item.url}>
<FormattedMessage {...MSG[`item_${index}`]} />
</NavLink>
</li>
);
});
const MSG = defineMessages({
item_0: {
id: 'items.service',
defaultMessage: 'Service'
},
item_1: {
id: 'items.contact',
defaultMessage: 'Contact'
}
})
答案 2 :(得分:0)
我最近遇到了同样的问题。 React Intl 不允许将数组传递给 <FormattedMessage />
,因此假设您有大量翻译项目,例如这个英文消息对象:
{
"page.title": "Test Page",
"page.menuItems": ["First english Item", "second english Item", ... , "100th english item"]
}
您需要一个解决方法。这个想法是我们希望通过嵌套索引而不是全局 id 访问这些项目。
现在我找到了两种解决方案来实现这一目标:
intl
消息中的嵌套消息(hacky & fast):import React from "react"
import {useIntl} from 'react-intl'
import NavLink from 'somewhere'
const Menu = ({menuItems}) => {
const intl = useIntl();
const menuItemsIntl = intl.messages["page.menuItems"];
return (<div>
{menuItems.map((item, index) =>
<li key={index}>
<NavLink to={item.url}>
{menuItemsIntl[index]}
</NavLink>
</li>}
</div>);
});
export default Menu;
这有一个缺点,即您没有 React Intl 的后备功能,以防您没有可用的翻译。您需要围绕 FormatMessage
编写自定义 menuItemsIntl[index]
组件来处理丢失的键。
我们需要消息对象看起来像这样:
{
"page.title": "Test Page",
"page.menuItems.1": "First english Item",
"page.menuItems.2": "Second english Item",
...
"page.menuItems.100": "100th english item"
}
为了得到它,我们需要扁平化原始消息对象,例如使用以下变异函数:
import translations from "./translations.json";
const Root = ()=> {
const [lan, setLan]= useState("en");
const messages = translations[lan]
const flattenMessages = (obj, parKey = "") => {
Object.keys(obj).forEach((key) => {
const currKey = parKey + (parKey.length > 0 ? "." : "") + key;
if (Array.isArray(obj[key]) || typeof obj[key] === 'object') {
flattenMessages (obj[key], currKey)
} else if (typeof obj[key] === "string") {
messages[currKey] = obj[key]
}
})
}
flattenMessages({...messages})
return <IntlProvider
key={lan}
messages={messages}
locale={lan}
defaultLocale="en"
>
<App />
</IntlProvider>
};
然后您就可以像习惯一样使用带有 id 的 FormattedMessage
。您只需要根据 jsx 中的迭代器计算 id 字符串。
const Menu = ({menuItems}) => {
return (<div>
{menuItems.map((item, index) =>
<li key={index}>
<NavLink to={item.url}>
<FormattedMessage id={`page.menuItems.${index}.title`} />
</NavLink>
</li>}
</div>);
});
我编写了第一个解决方案,以防有人不知道您可以直接访问消息对象。但是,对于大多数情况,我会推荐第二种解决方案。