如何在React 0.14中的选项标签内使用FormattedMessage?

时间:2015-10-30 17:19:53

标签: reactjs

我正在尝试将我的应用程序从React 0.12迁移到React 0.14,并且使用放置在select标签内的react-intl FormattedMessage对象的选项元素出现问题。

以下是JSX代码示例:

<select>
<option value="value1"><FormattedMessage message={this.getIntlMessage('key1')}/></option>
<option value="value2"><FormattedMessage message={this.getIntlMessage('key2')}/></option>
</select>

此代码在React 0.12中正常工作,我看到了我翻译的选项元素。

在反应0.14中,我收到了这个错误:

Only strings and numbers are supported as <option> children.

我在今年早些时候发生的React中追踪了这个变化集:

https://github.com/facebook/react/pull/3847/files

如何解决此问题?我不能成为唯一一个尝试使用国际化选项元素的人吗?

6 个答案:

答案 0 :(得分:14)

这一直是个问题。反应&lt; 0.14用于静默接受无效的DOM结构,在var data = [{ data: [ [1, 5], [2, 3] ], highlightColor: "#00FF00" }, { data: [ [1, 2], [2, 8] ], highlightColor: "#FF0000", }]; 元素内的<span>元素中。然后,浏览器将更正DOM结构,并使React管理的虚拟DOM与真实事物不同步。在尝试重新渲染现有组件而不是仅重新安装它们之前,您不会看到错误。

<option> V2.0.0,它将支持React 0.14,允许您使用Function-As-Child模式来自定义react-intl组件的呈现方式。请参阅this issue上的“功能 - 儿童支持”段落。

在你的情况下,你会这样做:

Formatted*

我认为目前的稳定版本1.2.1没有办法实现这一目标。

答案 1 :(得分:12)

我有同样的问题,并通过injectIntl​​()解决了它。

  

此函数用于包装组件,并将IntlProvider创建的intl上下文对象作为包装组件的prop进行注入。使用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)

希望有帮助...

答案 2 :(得分:2)

作为@Alexandre Kirszenberg回答的一个更好的替代方案,它也可以将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,
  // ...
}

答案 3 :(得分:1)

使用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>

example code

答案 4 :(得分:0)

使用injectIntl包装您要在其中使用API​​的组件,以便您可以使用API​​,例如formattedMessage等。见react-intl/wiki/API

答案 5 :(得分:0)

"react-intl": "2.4.0",
"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>