react-intl - 访问嵌套消息

Posted

技术标签:

【中文标题】react-intl - 访问嵌套消息【英文标题】:react-intl - accessing nested messages 【发布时间】:2018-01-28 17:39:21 【问题描述】:

我正在尝试在应用程序中使用 react-intl 包。该应用程序在服务器上呈现,因此我编写了一些代码来确定使用哪种语言并将其提供给IntlProvider

messages.js 文件中提供了翻译,它们看起来像这样:

export default 
  en: 
    message: '...some message',
    nested: 
      anotherMessage: '...another message',
    
  
  de: 
    // ...
  

我做的是这样的:

// import messages from './messages.js'
// Check the locale for the user (based on cookies or other things)
const locale = ...
// Get the required messages
const messagesForLocale= = messages[locale];
// Supply the messages to the IntlProvider
<IntlProvider locale=locale messages=messagesForLocale>
  // ...
</IntlProvider>

然后当我使用FormattedMessage 组件时,我无法使用如下代码访问嵌套消息(anotherMessage):

<FormattedMessage id="nested.anotherMessage" ... />

但是message 是可以访问的。

我犯了错误的任何想法,或者我在整个概念中遗漏了什么?

【问题讨论】:

【参考方案1】:

由于 React Intl v2 不再支持嵌套消息对象,消息需要扁平化。

export const flattenMessages = ((nestedMessages, prefix = '') => 
  if (nestedMessages === null) 
    return 
  
  return Object.keys(nestedMessages).reduce((messages, key) => 
    const value       = nestedMessages[key]
    const prefixedKey = prefix ? `$prefix.$key` : key

    if (typeof value === 'string') 
      Object.assign(messages,  [prefixedKey]: value )
     else 
      Object.assign(messages, flattenMessages(value, prefixedKey))
    

    return messages
  , )
)

// Use flattenMessages
<IntlProvider locale=locale messages=flattenMessages(messagesForLocale)>

参考:

https://github.com/yahoo/react-intl/wiki/Upgrade-Guide#flatten-messages-object https://github.com/yahoo/react-intl/issues/162#issuecomment-139683466

【讨论】:

谢谢。我们决定使用I18next,因为这似乎是一个更灵活的库。 非常感谢! 不知道react-intl是从雅虎开始的!【参考方案2】:

react-intl 不再支持嵌套消息。如果您仍想以这种方式组织您的消息,您可以使用 flat 库预先更正您的消息结构。

import flatten from 'flat'

<IntlProvider locale=locale messages=flatten(messagesForLocale)>

react-intl 的贡献者声称,仅支持扁平消息结构的主要原因是:

简单和灵活是主要原因。使用平面对象,人们可以编写他们想要的任何消息 ID/键,并且不会用特殊语义来解释它们。

在 GitHub 上查看问题 Support nested messages-object 评论。

【讨论】:

【参考方案3】:

是的,使用 flattenMessages 进行自定义是我发现的最佳方式。

这是供您参考的视频演示。

https://egghead.io/lessons/react-convert-a-hard-coded-string-using-react-intl-formattedmessage

【讨论】:

以上是关于react-intl - 访问嵌套消息的主要内容,如果未能解决你的问题,请参考以下文章

用户脚本绕过访问嵌套 iframe 的同源策略

XSLT 访问和创建嵌套 xml 并将标签转换为属性

SPRING BATCH:嵌套异常是java.sql.SQLException:ORA-08177:无法序列化此事务的访问权限

React-intl,使用 api 和 Typescript

React-Intl:消息未在 Safari 中格式化

如何处理 React-Intl 消息的多次使用?