React SSR - 处理window.height / width

时间:2016-07-03 17:05:41

标签: meteor reactjs server-side

我正在使用React和SSR FlowRouter。

由于这一行:

var height = (Meteor.isClient ? window.innerHeight : 0);
<div style={{top: height+'px' }}>

我收到了这样的警告:

Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server.

我知道这是因为客户端和服务器代码之间存在差异(我无法访问服务器上的窗口)。

有没有办法避免这种警告?

1 个答案:

答案 0 :(得分:2)

您面临的警告是由于服务器上最初呈现的html与客户端之间的校验和错误。正如您正确指出的那样,这是因为您在服务器上没有window对象,因此无法计算window.innerHeight。这导致呈现的html在style的{​​{1}}属性中不同并导致警告。

可能的解决方法是将div变量移动到组件的height并将其设置为初始状态0.然后执行检查

state
this.setState({height: (Meteor.isClient ? window.innerHeight : 0)});

并在此处设置正确的高度。这样,客户端和服务器的初始渲染将是相同的。但是,由于componentWillMount仅在客户端上调用,因此当componentDidMount发生更改时,它将使用height中的正确window重新呈现组件。

来自docs

  

如果您故意需要在服务器和客户端上呈现不同的内容,则可以执行两次渲染。在客户端上呈现不同内容的组件可以读取像state这样的状态变量,您可以在this.state.isClient中将其设置为true。这样,初始渲染过程将呈现与服务器相同的内容,从而避免不匹配,但在水合后立即同步进行额外的过程。请注意,这种方法会使组件变慢,因为它们必须渲染两次,因此请谨慎使用。