I'm trying to use react-intl
package inside an app. The app is rendered on the server so I wrote some code to determine which language to use and serve into IntlProvider
.
Translations were provided in messages.js
file and they look like this:
export default {
en: {
message: '...some message',
nested: {
anotherMessage: '...another message',
}
}
de: {
// ...
}
}
What I do is something like this:
// 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>
Then when I use FormattedMessage
component I can't access the nested message (anotherMessage
) with code like this:
<FormattedMessage id="nested.anotherMessage" ... />
But message
is accessible.
Any ideas where I made the mistake, or maybe I'm missing something in the whole concept?
Since React Intl v2 no longer supports nested messages objects, the messages need to be flattening.
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)}>
refs:
import flatten from 'flat'
<IntlProvider locale={locale} messages={flatten(messagesForLocale)}>
Yes, customization using flattenMessages is the best way I found.
Here is the video demo for your reference.
https://egghead.io/lessons/react-convert-a-hard-coded-string-using-react-intl-formattedmessage
来源:https://stackoverflow.com/questions/45783677/react-intl-accessing-nested-messages