2016-07-03 25 views
5

Sto usando React con SSR FlowRouter.React SSR - handle window.height/width

A causa di queste righe:

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

ottengo un avvertimento:

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.

lo so questo è a causa della differenza tra il client e il codice del server (non ho accesso ai finestra sul mio server).

C'è un modo per evitare questo avviso?

+1

Grazie per aver postato, l'hai capito? – Coherent

risposta

2

L'avviso che si sta affrontando è a causa di un errore di checksum tra l'html inizialmente visualizzato sul server e il client. Come hai giustamente sottolineato, questo perché, non hai l'oggetto window sul server e, quindi, non è possibile calcolare window.innerHeight. Ciò causa la modifica dell'html reso nell'attributo style di div e causa l'avviso.

Una possibile soluzione potrebbe essere quella di spostare la variabile height alla state del componente e impostarlo a uno stato iniziale di 0. Quindi eseguire il controllo

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

in componentWillMount e impostare l'altezza corretta qui. In questo modo il rendering iniziale di client e server sarebbe lo stesso. Tuttavia, dal momento che lo viene richiamato solo sul client, il nuovo componente verrà corretto con lo height corretto da window quando viene modificato lo state.

Dal docs

Se avete bisogno di rendere intenzionalmente qualcosa di diverso sul server e il client, si può fare un rendering a due passaggi. I componenti che eseguono il rendering di qualcosa di diverso sul client possono leggere una variabile di stato come this.state.isClient, che è possibile impostare su true in componentDidMount(). In questo modo il passaggio di rendering iniziale renderà lo stesso contenuto del server, evitando disallineamenti, ma un passaggio aggiuntivo avverrà in modo sincrono subito dopo l'idratazione. Nota che questo approccio renderà i tuoi componenti più lenti perché devono eseguire il rendering due volte, quindi usalo con cautela.