首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用React-Intl呈现格式化消息列表

如何使用React-Intl呈现格式化消息列表
EN

Stack Overflow用户
提问于 2018-10-11 00:56:10
回答 3查看 3.6K关注 0票数 7

我有一个标准的项目,如:联系方式,服务,价格等navigation…我将其呈现为:

代码语言:javascript
复制
const menuItemList = menuItems.map((item, index) => {
    return (
        <li key={index}>
            <NavLink to={item.url}>{item.title}</NavLink>
        </li>
    );
});

它工作得很好。但是现在我需要翻译这个导航,为此我使用了react-intl库。因此,对于react-intl doc,我必须像这样使用FormattedMessage

代码语言:javascript
复制
<p>
   <FormattedMessage id="mainText"/>
</p> 

它起作用了。但是我如何使用它来呈现列表呢?我认为它可以和这个一起工作,但是它不能。

代码语言:javascript
复制
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呈现包含项目的列表

EN

回答 3

Stack Overflow用户

发布于 2018-10-22 17:21:50

您需要将消息传递给intl。例如:

代码语言:javascript
复制
{
    profile: 'Profile',
    settings: 'Settings'
}

另外,我想你已经

代码语言:javascript
复制
const menuItems = [
    {
        url: '/profile',
        title: 'profile'
    },
    {
        url: '/settings',
        title: 'settings'
    }
] 

所以你可以这样使用它

代码语言:javascript
复制
const menuItemsList = menuItems.map((item, index) => {
    return (
        <li key={index}>
            <NavLink to={item.url}>
                <FormattedMessage id={item.title} />
            </NavLink>
        </li>
    );
});
票数 1
EN

Stack Overflow用户

发布于 2021-04-05 21:52:51

我最近也遇到了同样的问题。React Intl不允许将数组传递给<FormattedMessage />,因此假设您有大量已翻译的项,如此英语消息对象中的:

代码语言:javascript
复制
{
    "page.title": "Test Page",
    "page.menuItems": ["First english Item", "second english Item", ... , "100th english item"]
}

你需要一个变通的方法。我们的想法是,我们希望通过嵌套索引而不是全局id来访问这些项。

现在我找到了两个解决方案来解决这个问题:

  1. 通过索引(hacky &fast)直接访问intl消息中的嵌套消息:

代码语言:javascript
复制
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组件来处理缺少的键。

  1. 在将messages对象注入提供程序之前将其展平,然后通过计算出的唯一键(安全且健壮)访问它:

我们需要messages对象看起来像这样:

代码语言:javascript
复制
{
    "page.title": "Test Page",
    "page.menuItems.1": "First english Item", 
    "page.menuItems.2": "Second english Item", 
    ...
    "page.menuItems.100": "100th english item"
}

为了做到这一点,我们需要扁平化原始的messages对象,例如使用下面的变异函数:

代码语言:javascript
复制
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字符串。

代码语言:javascript
复制
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对象。然而,在大多数情况下,我会再次推荐第二种解决方案。

票数 1
EN

Stack Overflow用户

发布于 2019-06-14 16:20:55

您可以使用defineMessages

代码语言:javascript
复制
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'
  }
})
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52745263

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档