SetState在回调中失败(通过ComponentWillMount),仅在服务器上失败

时间:2015-09-15 22:42:03

标签: reactjs

我需要在服务器上呈现React组件以进行SEO。我的组件基于查询参数在ComponentWillMount中获取数据 - 但在服务器(节点4.0.0)上,SetState在请求的回调中失败。错误可以使用更简单的setTimeout重现,如下面的代码示例所示。

我在网上发现了很多关于React和服务器端渲染之间复杂性的讨论。我正在研究两种解决方法:

  • 从服务器中删除所有ajax请求,而不是将请求的结果直接呈现为嵌入在first-serve HTML中的全局变量
  • 在React组件初始化之前移动ajax请求,仅在服务器上(请求仍然必须存在ComponentWillMount(或ComponentDidMount)客户端版本。

如果有替代或推荐的方法,请告诉我。

var React = require('react');

// Reproduced in React 0.13.3 and 0.14.0-beta1
var ReactDOMServer = require("react-dom/server");

var A = React.createClass({
    componentWillMount: function() {
        var _this = this;
        // for example an ajax call to fetch data based on request parameters:
        setTimeout(function(err, res) {
            // state is set based on results
            _this.setState({ a: 1 });
        }, 100);
    },
    render: function() {
        return React.createElement('div', null);
    }
});

ReactDOMServer.renderToString(React.createElement(A, null));

错误:

$ node index.js 
/app/node_modules/react/lib/getActiveElement.js:25
    return document.body;
           ^

ReferenceError: document is not defined
    at getActiveElement (/app/node_modules/react/lib/getActiveElement.js:25:12)
    at ReactReconcileTransaction.ReactInputSelection.getSelectionInformation (/app/node_modules/react/lib/ReactInputSelection.js:38:23)
    at ReactReconcileTransaction.Mixin.initializeAll (/app/node_modules/react/lib/Transaction.js:168:75)
    at ReactReconcileTransaction.Mixin.perform (/app/node_modules/react/lib/Transaction.js:135:12)
    at ReactUpdatesFlushTransaction.Mixin.perform (/app/node_modules/react/lib/Transaction.js:136:20)
    at ReactUpdatesFlushTransaction.assign.perform (/app/node_modules/react/lib/ReactUpdates.js:86:38)
    at Object.flushBatchedUpdates (/app/node_modules/react/lib/ReactUpdates.js:147:19)
    at Object.wrapper [as flushBatchedUpdates] (/app/node_modules/react/lib/ReactPerf.js:66:21)
    at ReactDefaultBatchingStrategyTransaction.Mixin.closeAll (/app/node_modules/react/lib/Transaction.js:202:25)
    at ReactDefaultBatchingStrategyTransaction.Mixin.perform (/app/node_modules/react/lib/Transaction.js:149:16)

问题已于https://github.com/facebook/react/issues/4873

开启

1 个答案:

答案 0 :(得分:-1)

尝试在另一种方法中移动setState函数:

  var React = require('react');

  // Reproduced in React 0.13.3 and 0.14.0-beta1
  var ReactDOMServer = require("react-dom/server");
  var A = React.createClass({
    stateChange: function( obj ){
        setTimeout( this.setState( obj ), 100 );
    },
    componentWillMount: function() {
        this.stateChange( {a: 1} );
    },
    render: function() {
        console.log( this.state.a )
        return React.createElement('div', null);
    }
  }); 

  ReactDOMServer.renderToString(React.createElement(A, null));