React項目國際化-React-intl
import {IntlProvider} from "react-intl";
ReactDOM.render(
<React.StrictMode>
<IntlProvider locale='en-us'>
<App />
</IntlProvider>
</React.StrictMode>,
document.getElementById('root')
);
怎么翻譯項目中的文本?翻譯文件放到什么地方?通常來說,會為每一種語言提供一個翻譯文件(json文件),src/translations/zh.json提供中文翻譯 . en.json file 提供英文翻譯。假設要翻譯App.js中的內容,src/translations/en.json
{ "app.learn-react-link": "Learn React.", "app.text": "Edit <code>src/App.js</code> and save to reload." }
src/translations/zh.json
{ "app.learn-react-link": "學習 React.", "app.text": "編輯<code>src/App.js</code>,保存,并刷新頁面" }
項目中怎么獲取到翻譯文件? <IntlProvider />有messages屬性, 把locale設置的語言對應的翻譯內容,傳給它,就可以為項目提供翻譯內容。比如locale是en-us,那就要把en.json中的翻譯內容傳遞給messsages. locale是zh-cn,那就把zh.json中的翻譯內容傳遞給messages。怎么傳遞,只能先把json文件引入到項目中,再構建一個以locale為屬性,翻譯內容為值的對象,讓messages的值根據locale來定。index.js中
import zh from './translations/zh.json'; import en from './translations/en.json'; const messages = { 'en-us': en, 'zh-cn': zh } const locale = 'zh-cn'; ReactDOM.render( <React.StrictMode> <IntlProvider locale={locale} messages={messages[locale]}> <App /> </IntlProvider> </React.StrictMode>, document.getElementById('root') );
組件中怎么使用翻譯內容?最簡單的方法就是把要翻譯的文本使用<FormattedMessage> 組件來代替。組件有一個必傳屬性id,用來引用翻譯文件。怎么理解id呢?IntlProvider 的messages屬性實際上是一個js對象,包含著項目中每一句文本的翻譯,格式為{"app.learn-react-link": "學習 React."},"app.learn-react-link"可以看作組件中使用翻譯時引用的id,react-intl自動會引用id 對應的翻譯好的文本。<FormattedMessage> 中的id就是引用的這個id,也就是說,id必須和messages中指向json文件中的id一致。App.js
import {FormattedMessage} from 'react-intl';
<p><FormattedMessage id="app.text" /></p>
<a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer">
<FormattedMessage id="app.learn-react-link" />
</a>
npm start, 可以看到項目已經翻譯成中文了。能不能把<code> 去掉呢?FormattedMessage 可以在value屬性中解析出富文本中的XML標簽。FormattedMessage 有一個value屬性
<FormattedMessage id="app.text" values={{ code: chunks => <code>{chunks}</code> }} > </FormattedMessage>
code對應的就是app.text中的<code></code>標簽, 要解析富文本中的哪個標簽,屬性就是哪個標簽。chunks就可解析出標簽中的的內容,在這里就是code標簽中的內容,src/App.js, 返回值就是替換整個標簽及內容。但此時有個問題,如果有一種語言,恰好沒有翻譯呢?比如把locale改成en,
const locale = 'en';
頁面就只顯示app.text和app.learn-react-link 等Id

這時要用<FormattedMessage />的defaultMessage屬性,設置默認展示的文本。 如果此文本沒有在翻譯文件中找到,就顯示默認文本。它還有一個description: 描述這個文本的作用,主要為翻譯者提供上下文。
<FormattedMessage id="app.text" values={{ code: chunks => <code>{chunks}</code> }} defaultMessage="編輯<code>src/App.js</code>,保存,并刷新頁面" description="edit text" > <FormattedMessage id="app.learn-react-link" defaultMessage="學習 React." description="text link" />
import React from 'react'; import { useIntl } from 'react-intl'; export function Input() { const intl = useIntl(); const placeholder = intl.formatMessage({id: 'app.placeholder'}) return <input placeholder={placeholder}></input> }
引入useIntl,在組件中調用它,返回intl上下文,調用formatMessage方法,它接受一個對象作為參數,id屬性就是對應翻譯文件中的id。不要忘了在,json文件中寫
"app.placeholder": "請輸入數字"
當然,id屬性可以是動態生成的,比如
const intlKey = "something" const placeholder = intl.formatMessage({ id: `${intlKey}` })
import { defineMessages } from 'react-intl'
export default defineMessages({
text: {
id: 'app.text',
defaultMessage: 'Edit <code>src/App.js</code>'
},
link: {
id: 'app.learn-react-link',
defaultMessage: 'Lerne React',
description: 'Link on react page'
},
});
<FormattedMessage /> and formatMessage()就可以使用message.js中定義的text和link。App.js
import messages from './message.js' import { FormattedMessage } from 'react-intl' <p> <FormattedMessage {...messages.text} values={{ code: chunks => <code>{chunks}</code> }} > </FormattedMessage> </p> <a className="App-link" href="https://reactjs.org" target="_blank" > <FormattedMessage {...messages.link} /> </a>
Input.js
import { useIntl } from 'react-intl';
import messages from './message'
export function Input() {
const intl = useIntl();
const placeholder = intl.formatMessage(messages.placeholder)
return <input placeholder={placeholder}></input>
}
如果不能使用useIntl hooks, 在普通函數或類組件中可以使用injectIntl函數提供intl上下文。Input.js
import React from 'react'; import messages from './message.js' import { injectIntl } from 'react-intl' function Input({intl}) { const placeholder = intl.formatMessage(messages.placeholder) return <input placeholder={placeholder}></input> } export default injectIntl(Input);
使用類
import React from 'react'; import messages from './message.js' import { injectIntl } from 'react-intl' class Input extends React.Component { render() { const {intl} = this.props; const placeholder = intl.formatMessage(messages.placeholder) return <input placeholder={placeholder}></input> } } export default injectIntl(Input);

浙公網安備 33010602011771號