React - react -intl 中FormattedMessage组件中如何传递参数
在 react-intl 的 FormattedMessage 组件中,可以通过 values 属性来传递参数。这个属性接收一个对象,对象的键对应消息中的变量名。
基本用法
1. 简单变量替换
首先,在语言文件中定义带有变量的消息:
src/locales/en.json
{
"greeting": "Hello, {name}!",
"welcome": "Welcome, {username}. You have {count} messages.",
"product.info": "Product: {productName}, Price: {price}"
}
src/locales/zh.json
{
"greeting": "你好,{name}!",
"welcome": "欢迎,{username}。您有 {count} 条消息。",
"product.info": "产品:{productName},价格:{price}"
}
然后在组件中传递参数:
import React from "react";
import { FormattedMessage } from "react-intl";
function UserGreeting() {
return (
<div>
{/* 传递字符串参数 */}
<h1>
<FormattedMessage id="greeting" values={{ name: "张三" }} />
</h1>
{/* 传递多个参数 */}
<p>
<FormattedMessage
id="welcome"
values={{
username: "李四",
count: 5,
}}
/>
</p>
</div>
);
}
2. 传递动态数据
可以从组件的 state、props 或变量中传递动态数据:
import React, { useState } from "react";
import { FormattedMessage } from "react-intl";
function UserDashboard({ user }) {
const [messageCount, setMessageCount] = useState(10);
return (
<div>
{/* 从 props 传递数据 */}
<FormattedMessage id="greeting" values={{ name: user.name }} />
{/* 从 state 传递数据 */}
<FormattedMessage
id="welcome"
values={{
username: user.username,
count: messageCount,
}}
/>
{/* 传递计算结果 */}
<FormattedMessage
id="product.info"
values={{
productName: "笔记本电脑",
price: `$${user.balance}`,
}}
/>
</div>
);
}
高级用法
1. 传递 React 组件作为参数
FormattedMessage 的 values 属性不仅可以传递字符串和数字,还可以传递React 组件,实现富文本格式化:
import React from "react";
import { FormattedMessage } from "react-intl";
function RichTextExample() {
return (
<div>
<FormattedMessage
id="terms.agreement"
values={{
// 传递链接组件
termsLink: (chunks) => <a href="/terms">{chunks}</a>,
privacyLink: (chunks) => <a href="/privacy">{chunks}</a>,
// 传递带样式的文本
bold: (chunks) => <strong>{chunks}</strong>,
}}
/>
</div>
);
}
对应的语言文件:
{
"terms.agreement": "I agree to the {termsLink}Terms of Service{/termsLink} and {privacyLink}Privacy Policy{/privacyLink}. This is {bold}important{/bold}."
}
2. 格式化数字和日期
可以在传递参数前进行格式化,或者结合其他 react-intl 组件:
import React from "react";
import { FormattedMessage, FormattedNumber, FormattedDate } from "react-intl";
function ProductDisplay({ product }) {
return (
<div>
{/* 方法1:传递格式化后的值 */}
<FormattedMessage
id="product.info"
values={{
name: product.name,
price: (
<FormattedNumber
value={product.price}
style="currency"
currency="USD"
/>
),
date: (
<FormattedDate
value={product.releaseDate}
year="numeric"
month="long"
day="numeric"
/>
),
}}
/>
{/* 方法2:在 values 中直接传递数字,让 react-intl 自动格式化 */}
<FormattedMessage
id="product.stats"
values={{
sales: product.sales,
rating: product.rating,
}}
/>
</div>
);
}
语言文件:
{
"product.info": "Product: {name}, Price: {price}, Released: {date}",
"product.stats": "Sales: {sales, number} units, Rating: {rating, number, ::.1f}"
}
3. 条件格式化(复数化)
react-intl 支持 ICU 消息语法,可以在消息内部处理复数逻辑:
{
"messages.count": "You have {count, plural, =0 {no messages} one {# message} other {# messages}}.",
"items.count": "{count, plural, =0 {No items} one {1 item} other {{count} items}} in cart"
}
使用时只需传递数字参数:
function MessageCounter({ count }) {
return (
<div>
<FormattedMessage id="messages.count" values={{ count: count }} />
</div>
);
}
// 使用示例:
// count = 0 -> "You have no messages."
// count = 1 -> "You have 1 message."
// count = 5 -> "You have 5 messages."
4. 传递数组
function CategoryList({ categories }) {
return (
<div>
<FormattedMessage
id="categories.display"
values={{
// 传递数组并格式化
list: categories.join(", "),
// 或者传递整个数组
items: categories,
}}
/>
</div>
);
}
语言文件:
{
"categories.display": "Categories: {list}. Total: {items.length} items"
}
完整的实际示例
import React, { useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
function ShoppingCart() {
const [cart, setCart] = useState([
{ id: 1, name: "Laptop", price: 999.99, quantity: 1 },
{ id: 2, name: "Mouse", price: 29.99, quantity: 2 },
]);
const intl = useIntl();
const total = cart.reduce((sum, item) => sum + item.price * item.quantity, 0);
return (
<div>
<h2>
<FormattedMessage id="cart.title" />
</h2>
{cart.map((item) => (
<div key={item.id}>
<FormattedMessage
id="cart.item"
values={{
name: item.name,
price: intl.formatNumber(item.price, {
style: "currency",
currency: "USD",
}),
quantity: item.quantity,
// 使用组件作为参数
removeButton: (chunks) => (
<button onClick={() => removeItem(item.id)}>{chunks}</button>
),
}}
/>
</div>
))}
<div className="total">
<FormattedMessage
id="cart.total"
values={{
total: intl.formatNumber(total, {
style: "currency",
currency: "USD",
}),
itemCount: cart.length,
}}
/>
</div>
<button>
<FormattedMessage
id="cart.checkout"
values={{ itemCount: cart.length }}
/>
</button>
</div>
);
}
export default ShoppingCart;
对应的语言文件:
{
"cart.title": "Shopping Cart",
"cart.item": "{name} - {price} x {quantity} {removeButton}Remove{/removeButton}",
"cart.total": "Total: {total} ({itemCount, plural, =0 {no items} one {# item} other {# items}})",
"cart.checkout": "Checkout ({itemCount, plural, =0 {empty} other {# items}})"
}
总结
| 参数类型 | 示例 | 说明 |
|---|---|---|
| 字符串 | values={{ name: '张三' }} |
最简单的文本替换 |
| 数字 | values={{ count: 5 }} |
用于计数或配合复数语法 |
| 组件 | values={{ link: (chunks) => <a>{chunks}</a> }} |
实现富文本 |
| 格式化值 | values={{ price: <FormattedNumber value={99.9} /> }} |
嵌套使用其他格式化组件 |
| 数组 | values={{ items: ['a', 'b'] }} |
传递列表数据 |
values 属性非常灵活,可以满足各种动态内容的国际化需求。

浙公网安备 33010602011771号