Reactjs 如何在React 0.14中的选项标记内使用FormattedMessage?
我正在尝试将我的应用程序从React 0.12迁移到React 0.14,并且在使用放置在select标记中的FormattedMessage对象的选项元素时遇到问题 下面是一个示例JSX代码:Reactjs 如何在React 0.14中的选项标记内使用FormattedMessage?,reactjs,Reactjs,我正在尝试将我的应用程序从React 0.12迁移到React 0.14,并且在使用放置在select标记中的FormattedMessage对象的选项元素时遇到问题 下面是一个示例JSX代码: <select> <option value="value1"><FormattedMessage message={this.getIntlMessage('key1')}/></option> <option value="value2">
<select>
<option value="value1"><FormattedMessage message={this.getIntlMessage('key1')}/></option>
<option value="value2"><FormattedMessage message={this.getIntlMessage('key2')}/></option>
</select>
这段代码在React 0.12中运行良好,我看到了已翻译的选项元素
在react 0.14中,我得到了以下错误:
Only strings and numbers are supported as <option> children.
仅支持将字符串和数字作为子项。
我在今年早些时候的React中跟踪了这条消息:
如何解决此问题?我不是唯一一个尝试使用国际化选项元素的人?这一直是个问题。React<0.14用于以静默方式接受无效的DOM结构,在您的情况下是
元素中的
元素。然后,浏览器将更正DOM结构,并导致React管理的虚拟DOM与真实DOM不同步。在尝试重新呈现现有组件而不是重新装载它们之前,您不会看到错误
react intl
V2.0.0将附带对react 0.14的支持,它允许您使用函数作为子模式来自定义格式化的*
组件的渲染方式。请参见上的“作为子女抚养人的职能”一段
在您的情况下,您将执行以下操作:
{(消息)=>{message}
{(消息)=>{message}
我认为在当前的稳定版本1.2.1上没有办法实现这一点。作为@Alexandre Kirszenberg answer更好的替代方案,也可以将
intl
对象注入组件并直接使用formatMessage
函数
import { injectIntl, intlShape, defineMessages, FormattedMessage } from 'react-intl';
const AddressForm = ({ intl, street, number, postalCode, city, onChange }) => {
return (
<form id="paymentAddress">
// ...
<fieldset className="form-group">
<label htmlFor="country"><FormattedMessage { ...messages.country } />:</label>
<div>
<select name="country">
<option value="DE">{intl.formatMessage(messages.de)}</option>
<option value="UK">{intl.formatMessage(messages.uk)}</option>
<option value="CH">{intl.formatMessage(messages.ch)}</option>
</select>
</div>
</fieldset>
</form>
);
};
AddressForm.propTypes = {
intl: intlShape.isRequired,
// ...
}
从'react intl'导入{injectIntl,intlShape,defineMessages,FormattedMessage};
const AddressForm=({intl,street,number,postalCode,city,onChange})=>{
返回(
// ...
:
{intl.formatMessage(messages.de)}
{intl.formatMessage(messages.uk)}
{intl.formatMessage(messages.ch)}
);
};
AddressForm.propTypes={
intl:intlShape.isRequired,
// ...
}
我遇到了同样的问题,并通过injectIntl()解决了它
此函数用于包装组件,并将IntlProvider创建的intl上下文对象作为道具注入包装组件。使用HOC工厂函数可以减少将上下文作为公共API一部分的需要
这意味着您只需使用injectIntl函数包装组件,如下所示:
import React, {Component, PropTypes} from 'react';
import {defineMessages, injectIntl, intlShape} from 'react-intl';
const messages = defineMessages({
firstoption: {
id: 'mycomponent.firstoption',
defaultMessage: 'Coffee',
},
secondoption: {
id: 'mycomponent.secondoption',
defaultMessage: 'Tea',
}
});
class MyComponent extends Component {
render() {
const {formatMessage} = this.props.intl;
return (
<div>
<select>
<option value="value1">{formatMessage(messages.firstoption)}</option>
<option value="value2">{formatMessage(messages.secondoption)}</option>
</select>
</div>
);
}
}
MyComponent = {
intl : intlShape.isRequired
};
export default injectIntl(MyComponent)
import React,{Component,PropTypes}来自'React';
从'react intl'导入{defineMessages,injectIntl,intlShape};
常量消息=定义消息({
第一种选择:{
id:'mycomponent.firstoption',
defaultMessage:“咖啡”,
},
第二种选择:{
id:'mycomponent.secondoption',
defaultMessage:'茶',
}
});
类MyComponent扩展组件{
render(){
const{formatMessage}=this.props.intl;
返回(
{formatMessage(messages.firstoption)}
{formatMessage(messages.secondoption)}
);
}
}
MyComponent={
intl:intlShape.isRequired
};
导出默认injectIntl(MyComponent)
希望这有助于…使用
injectIntl
包装您想要在其中使用API的组件,这样您就可以使用API,例如formattedMessage
等等。请参见使用react intl
v4.0.0您可以执行以下操作:
<select
className="content"
name="type-enquiry"
defaultValue="Type of Enquiry"
onChange={handleChange}
required
>
<option name="options" disabled hidden>
Choose
</option>
<FormattedMessage id='contact.enquiry.a' key={'op' + '-' + 'a'}>
{(message) => <option value='a'>{message}</option>}
</FormattedMessage>
<FormattedMessage id='contact.enquiry.b' key={'op' + '-' + 'b'}>
{(message) => <option value='b'>{message}</option>}
</FormattedMessage>
<FormattedMessage id='contact.enquiry.c' key={'op' + '-' + 'c'}>
{(message) => <option value='c'>{message}</option>}
</FormattedMessage>
</select>
选择
{(消息)=>{message}
{(消息)=>{message}
{(消息)=>{message}
工作片段
<FormattedMessage
key={key}
id={popoverOptions[key].id}
defaultMessage={popoverOptions[key].defaultMessage}>
{(message) => <option value={key}>{message}</option>}
</FormattedMessage>
{Object.keys(popoverOptions).map((键,索引)=>{
返回(
{(消息)=>{message}
)
})}
如果OP不需要进行格式化,他们可以在选项中执行这个.getIntlMessage('key1')
?有点疏忽,没有公开完整的底层翻译方法。你是对的,在OP的例子中,this.getIntlMessage('key1')
将返回正确的消息。请注意,V2.0.0API确实公开了上下文上的翻译方法。只要我不使用任何占位符,它似乎就可以工作。。。。我不敢相信没有稳定的方法可以做到这一点?如果我必须在多个组件上使用格式,那又如何呢。我在哪里可以本地注入intl属性,这样当用户调用格式化消息时,他就不必每次都注入intl。因此,当您使用组件时,您将向所需的intl属性传递什么?我假设这是由注入处理的,但是我在使用组件的编辑器中得到一个错误,说缺少必需的属性intl。这只是编辑问题吗?“MyComponent=”应该是“MyComponent.propTypes=”。。。?
"babel-plugin-react-intl": "2.4.0",
<FormattedMessage
key={key}
id={popoverOptions[key].id}
defaultMessage={popoverOptions[key].defaultMessage}>
{(message) => <option value={key}>{message}</option>}
</FormattedMessage>
"reactstrap": "5.0.0-beta",
import { Input} from "reactstrap";
import {FormattedMessage} from "react-intl";
<Input
value={filter.status}
onChange={this.onFilterChange}
type="select"
name="select" id="exampleSelect">
{Object.keys(popoverOptions).map((key, index) => {
return (
<FormattedMessage
key={key}
id={popoverOptions[key].id}
defaultMessage={popoverOptions[key].defaultMessage}>
{(message) => <option value={key}>{message}</option>}
</FormattedMessage>
)
})}
</Input>