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

Jas*_*ead 10 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>
Run Code Online (Sandbox Code Playgroud)

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

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

Only strings and numbers are supported as <option> children.
Run Code Online (Sandbox Code Playgroud)

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

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

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

Ale*_*erg 14

这一直是个问题.React <0.14用于静默接受无效的DOM结构,在你的case <span>元素内部<option>元素.然后,浏览器将更正DOM结构,并使React管理的虚拟DOM与真实事物不同步.在尝试重新渲染现有组件而不是仅重新安装它们之前,您不会看到错误.

react-intlV2.0.0将支持React 0.14,允许您使用Function-As-Child模式来自定义Formatted*组件的呈现方式.请参阅此问题的"功能 - 儿童支持"段落.

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

<FormattedMessage message={this.getIntlMessage('key1')}>
  {(message) => <option value="value1">{message}</option>}
</FormattedMessage>
<FormattedMessage message={this.getIntlMessage('key2')}>
  {(message) => <option value="value2">{message}</option>}
</FormattedMessage>
Run Code Online (Sandbox Code Playgroud)

我不认为在目前的稳定版本1.2.1上有办法实现这一点.

  • 只要我不使用任何占位符,它似乎会起作用....我不敢相信没有稳定的方法来做到这一点? (3认同)

Ale*_*der 13

我有同样的问题,并通过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)
Run Code Online (Sandbox Code Playgroud)

希望有帮助......