20

我正在尝试在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可以访问。

我犯了错误的任何想法,或者我在整个概念中遗漏了一些东西?

4

3 回答 3

25

由于 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)}>

参考:

于 2017-08-26T09:39:06.623 回答
11

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

import flatten from 'flat'

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

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

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

在 GitHub 上查看问题支持嵌套消息对象 评论。

于 2018-12-13T04:10:18.453 回答
1

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

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

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

于 2018-06-12T06:39:55.227 回答