2016-06-15 72 views
3

我努力使组件在客户端和服务器端都能够正常工作。服务器端渲染React通过Ajax加载状态的组件

这是我的组件代码:

export default class extends React.Component { 
    constructor(props, context) { 
     super(props, context); 

     this.state = { 
      title: props.params.title, 
      message: props.params.message 
     }; 
    } 

    componentDidMount() { 
     $.ajax({ 
      url: "/get-message", 
      success: function (result) { 
       this.setState({ 
        title: result.title, 
        message: result.message 
       }); 
      }.bind(this), 
      cache: false 
     }); 
    } 

    render() { 
     return (
      <div> 
       <h2>{this.state.title}</h2> 
       <h3>{this.state.message}</h3> 
      </div> 
     ); 
    } 
} 

它工作正常。当它通过客户端渲染时,它会显示h2h3为空,然后在ajax调用返回时填充它们。

当它通过服务器呈现时,我已经获得了这些道具填充和发送到客户端的HTML已经完成,并且不需要任何额外的东西。

的问题是,当它得到的服务器上呈现,我得到错误信息在客户端上:

Warning: React attempted to reuse markup in a container but the checksum was invalid. [...] 

它然后再调用AJAX方法和重新渲染一切。

那么我该如何处理这种情况呢?有没有办法告诉React这个组件在服务器上呈现接受它,而不是调用componentDidMount方法?

+0

你希望在服务器端呈现使Ajax调用?所以CLIENT会有FINAL标记? –

+0

ajax调用也会调用服务器端可用的方法,所以服务器上没有ajax调用。接受的答案做了我所需要的。谢谢 – user3900456

回答

3

处理这个问题的常用方法是使用全局状态。您可以在<body>标记的底部序列化JS对象,其中包含在服务器端计算的状态。

<script>globalState={MyFeature: {title: 'foo'}};</script> 

然后使用该状态(或其分支)作为组件的默认值。

例如

if (globalState.MyFeature.title) { 
    this.setState({ title: globalState.MyFeature.title }); 
} else { 
    $.ajax(/* ... */); 
} 

很明显,你可以使用终极版很好地管理您的全局状态,但你真的不需要来。但是,有很多有用的软件包可以帮助您简化此过程。