我有一个标准的项目,如:联系方式,服务,价格等navigation…我将其呈现为:
const menuItemList = menuItems.map((item, index) => {
return (
<li key={index}>
<NavLink to={item.url}>{item.title}</NavLink>
</li>
);
});它工作得很好。但是现在我需要翻译这个导航,为此我使用了react-intl库。因此,对于react-intl doc,我必须像这样使用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中使用react-intl中的FormattedMessage呈现包含项目的列表
发布于 2018-10-22 17:21:50
您需要将消息传递给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>
);
});发布于 2021-04-05 21:52:51
我最近也遇到了同样的问题。React Intl不允许将数组传递给<FormattedMessage />,因此假设您有大量已翻译的项,如此英语消息对象中的:
{
"page.title": "Test Page",
"page.menuItems": ["First english Item", "second english Item", ... , "100th english item"]
}你需要一个变通的方法。我们的想法是,我们希望通过嵌套索引而不是全局id来访问这些项。
现在我找到了两个解决方案来解决这个问题:
intl消息中的嵌套消息: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的回退功能。您需要围绕menuItemsIntl[index]编写自定义FormatMessage组件来处理缺少的键。
我们需要messages对象看起来像这样:
{
"page.title": "Test Page",
"page.menuItems.1": "First english Item",
"page.menuItems.2": "Second english Item",
...
"page.menuItems.100": "100th english item"
}为了做到这一点,我们需要扁平化原始的messages对象,例如使用下面的变异函数:
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>);
});我编写了第一个解决方案,以防有人不知道您可以直接访问messages对象。然而,在大多数情况下,我会再次推荐第二种解决方案。
发布于 2019-06-14 16:20:55
您可以使用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'
}
})https://stackoverflow.com/questions/52745263
复制相似问题