2016-07-16 14 views
1

Ich benutze Websockets im Browser, die das Fensterobjekt verwenden. Aber da ich das serverseitige Rendering mit react nutze. mein Server abstürzt und erhöht die unten Fehlermeldung, wennwie man mit window richtig umgehen kann = undefinierter Fehler beim Reagieren Server-Side-Rendering

[Error] ReferenceError: window is not defined 

besonders, weil einer meiner Komponenten benötigen Sie den Client-Socket für die Kommunikation mit dem Server zu kompilieren.

Ive versucht, den Code unten zu Beginn des

if (typeof(window) == 'undefined'){ 
    global.window = new Object(); 
} 

meine server.js Datei hinzufügen, aber es stellt sich nach wie vor um den Fehler aus irgendeinem Grund. Was kann ich noch tun? Hat sich jemand mit diesem Thema beschäftigt?

UPDATE - das Problem ist möglicherweise nicht nur für Socket spezifisch. Im Grunde bin ich importieren paar Objekte aus der folgenden Datei in meiner Komponente

import React from 'react'; 
import ReactDOM from 'react-dom'; 

import {Provider} from 'react-redux'; 
import {createStore} from 'redux'; 
import { Router, Route, browserHistory ,IndexRoute} from 'react-router' 
import routes from '../shared/routes/routes'; 
import rootReducer from '../shared/reducers/index'; 
import SocketCluster from 'socketcluster-client'; 

const initialState = window.__INITIAL_STATE__ 

export const store = createStore(rootReducer,initialState) 

const options = { 
    port: 3000 
} 

if(store.getState().User.isAuthenticated){ 
    const socket = SocketCluster.connect(options) 
} 

console.log(store.getState()) 

ReactDOM.render(
    <Provider store={store}> 
    <Router history={browserHistory}> 
     {routes} 
    </Router> 
    </Provider> 
    ,document.getElementById('app') 
) 

in meiner Komponente

import React from 'react'; 
import Skill from './skill'; 
import Select from 'react-select'; 
import {socket ,store} from '../../client/index'; 

ich bin den Fehler bekommen, weil aus irgendeinem Grund. Der Server schaut auch window.__INITIAL_STATE__ als auch. Das Problem ist, dass ich scheinbar nichts aus der index.js-Datei auf der Client-Seite importieren kann.

Was kann ich tun?

Antwort

1

Javascript muss nicht unbedingt eine Kompilierungsphase haben. Zugegeben, die meisten Implementierungen kompilieren, aber es gibt keine einzige Phase, in der dies geschieht. Der Zugriff auf die Variable window wird erst ausgelöst, wenn sie ausgeführt wird.

Wenn Sie React verwenden, ist der normale Weg, Code nur auf dem Client auszuführen, darin zu schreiben componentDidMount.

In jedem Fall würde ich raten, nicht zu versuchen, gefälschte Versionen von clientseitigen APIs auf dem Server zu erstellen, um einen Bruch zu verhindern. Stellen Sie stattdessen sicher, dass der clientseitige Code nur auf dem Client ausgeführt wird.

Sie könnten es in eine Funktion umhüllen und es nur von componentDidMount aufrufen, oder Sie könnten die Umgebung testen.

Ich sollte beachten, dass Server-Code aus Gründen der Sicherheit und Code-Größe vorzugsweise nie an den Client versendet werden sollte. Es ist besser, den Speicher von Code zu initialisieren, der auf dem Client überhaupt nicht verfügbar ist.

Es gibt keine Möglichkeit, diese Dinge zu tun, und es gibt Vor- und Nachteile für jede Methode.

Dan Abramov, der Schöpfer von Redux, glaube ich ist ein großer Befürworter, die Gründe für jedes Stück Code zu kennen, die Bibliotheken zu verstehen, die Sie verwenden, und eine Methode zu bevorzugen, die Sie über eine akzeptierte Standardmethode verstehen. Redux selbst basiert stark auf diesen Ideen, weshalb es nicht viel vorschreibt. Es ist auch der Grund, warum es so viele Add-Ons rund um Redux gibt.

Es ist nicht wirklich notwendig, den gesamten Code so zu erzwingen, dass er sowohl mit dem Server als auch mit dem Client kompatibel ist. Trennen Sie einfach die Teile, die unbedingt getrennt sein müssen.

+0

danke für diese ..Ich habe mir einige Beispiele für Server-gerenderte Redox-Apps angeschaut. insbesondere https://github.com/erikras/react-redux-universal-hot-example/blob/master/src/client.js. Der Autor hat das Socket-Objekt global gemacht. und bedingt Funktionen ausführt, wenn das Socket-Objekt verfügbar ist. es scheint so weit zu funktionieren – Kannaj

+0

Glaubst du, es ist in Ordnung, ein globales Objekt zu haben? – Kannaj

+0

Es ist normalerweise nicht notwendig, aber wenn es die Dinge wesentlich einfacher macht, ist es sicherlich erlaubt. Es kommt darauf an, ob Sie es für eine gute Idee halten. Im Allgemeinen verursacht jedoch das Vorhandensein globaler Daten Namespace-Probleme und Probleme bei der Wiederverwendung von Code. – DDS