React update intl dont work: Uncaught ReferenceError: Could not find Intl message:

React update intl dont work: Uncaught ReferenceError: Could not find Intl message:

我确实从 React 0.13 升级到了最新版本。这里是我更改的依赖项列表。

react: 0.13.3 -> 0.14.3  
react-dom: none  -> 0.14.3  
react-router: 0.13.3 -> 1.0.3  
react-history: none -> 1.0.3  
react-intl: 1.2.0 -> 1.2.2  
intl: 1.0.0 -> 1.0.1  

但是我无法让翻译再次工作。

未捕获的引用错误:找不到国际消息:测试

// app.js
var React = require('react');
var ReactDom = require('react-dom');
var Router = require('react-router').Router;
var routes = require('./routes');
var createHistory = require('history').createHistory;

var intlData = {
    locales: 'en',
    messages: {
        test: 'Test'
    }
};

ReactDom.render(<Router history={createHistory()} intl={intlData}>{routes}</Router>, document.getElementById('app'));


// Test.js
var React = require('react');
var ReactIntl = require('react-intl');
var IntlMixin = ReactIntl.IntlMixin;

var Test = React.createClass({

    mixins: [IntlMixin],

    render: function() {
        return (
            <div>
                <h1>
                    {this.getIntlMessage('test')}
                </h1>
            </div>
        );
    }
});

module.exports = Test;

我在更新中错过了什么?初始化消息的正确方法是什么。

IntlMixinlooking on the context for the relevant data, specifically, this.context.locales, this.context.formats, and this.context.messages 创作。可能是 React Router 从 0.x 升级到 1.x——这改变了顶级组件的处理方式——破坏了事情。

但是,如果您查看上面链接的源代码,您会发现 mixin 会在 this.context 上查找数据,仅当 在 [=] 上找不到数据时20=]。因此,如果您可以将您的国际化数据作为 prop 传递给每个路由处理程序,那么一切都会正常进行。幸运的是,React Router 允许你这样做 via createElement.

createElement 应该是一个带有两个参数的函数:React Router 想要渲染的组件,以及它想要发送给它的道具。该函数应该使用给定的道具渲染该组件。默认实现如下所示:

function createElement(Component, props) {
  return <Component {...props} />
}

但是,您可以进一步自定义组件的呈现方式。对于您的情况,它可能类似于:

function createIntlElement(Component, props) {
  return <Component intl={intlData} {...props} />
}

尽管从 React Intl 文档看来应该将 props 分开,所以如果这不起作用,也许更像是:

function createIntlElement(Component, props) {
  return <Component {...props}
                    locales={intlData.locales}
                    messages={intlData.messages} />
}

或者,更简单地使用传播语法,

function createIntlElement(Component, props) {
  return <Component {...props} {...intlData} />
}

然后您通过将 createElement 函数传递给 createElement 属性来指示路由器使用您的 createElement 函数:

var router = (
  <Router history={createHistory()} createElement={createIntlElement}>
    {routes}
  </Router>
);
ReactDom.render(router, document.getElementById('app'));

不要忘记在所有路由处理程序中包含 IntlMixin,以便 不是 直接由路由器呈现的子组件仍然可以访问上下文.


React Intl 版本 2(现在处于测试阶段)似乎使用 IntlProvider 组件,很像 Redux 的 Provider 组件,为您提供正确的上下文,因此使用 createElement使用该版本时不需要。