如何在反应服务器端渲染中正确处理 window=undefined 错误
Posted
技术标签:
【中文标题】如何在反应服务器端渲染中正确处理 window=undefined 错误【英文标题】:how to properly deal with window=undefined error in react server side rendering 【发布时间】:2016-07-16 14:24:06 【问题描述】:我在使用窗口对象的浏览器上使用 websockets。但是因为我使用的是带有反应的服务器端渲染。我的服务器在编译时崩溃并引发以下错误
[Error] ReferenceError: window is not defined
特别是因为我的一个组件需要客户端套接字才能与服务器通信。
我尝试在我的 server.js
文件的开头添加以下代码
if (typeof(window) == 'undefined')
global.window = new Object();
但由于某种原因它仍然会引发错误。我还能做什么?有人处理过这个问题吗?
更新 - 问题可能不只是特定于套接字。基本上,我正在从我的组件中的以下文件中导入几个对象
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')
)
在我的组件中
import React from 'react';
import Skill from './skill';
import Select from 'react-select';
import socket ,store from '../../client/index';
由于某种原因,我收到错误消息。服务器也在查看window.__INITIAL_STATE__
。所以问题是我似乎无法从客户端的 index.js 文件中导入任何内容。
我能做什么?
【问题讨论】:
【参考方案1】:javascript 不一定有编译阶段。诚然,大多数实现都可以编译,但没有一个阶段会发生这种情况。对window
变量的访问在执行之前不会抛出。
使用 React 时,仅在客户端运行代码的正常方法是将其放在 componentDidMount
中。
无论如何,我建议不要尝试在服务器上创建虚假版本的客户端 API 以防止损坏。相反,请确保您的客户端代码只在客户端上运行。
您可以将其包装在一个函数中并仅从componentDidMount
调用它,或者您可以测试环境。
function clientInitialize()
// start your client side app here
// create client-side store here
function serverInitialize()
// create server-side store here
if (typeof window === 'object')
clientInitialize();
else
serverInitialize();
我应该注意,出于安全性和代码大小的原因,最好不要将服务器端代码发送给客户端。最好使用客户端上根本不可用的代码来初始化商店。
没有一种方法可以做这些事情,每种方法都有优缺点。
我相信 Redux 的创建者 Dan Abramov 非常支持了解您拥有的每段代码的原因,了解您使用的库,并且更喜欢您理解的方法而不是公认的标准方法。 Redux 本身在很大程度上基于这些想法,这就是它没有太多规定的原因。这也是 Redux 周围有如此众多的插件社区的原因。
确实没有必要强制所有代码都与服务器和客户端兼容。只需将必须分开的部分分开即可。
【讨论】:
感谢...我正在查看一些服务器渲染的 react-redux 应用程序示例。特别是github.com/erikras/react-redux-universal-hot-example/blob/…。作者已将套接字对象设为全局。如果套接字对象可用,则有条件地执行函数。到目前为止它似乎有效 你认为拥有一个全局对象可以吗? 这通常不是必需的,但如果它使事情变得更加简单,那当然是允许的。这一切都取决于你是否认为这是一个好主意。然而,一般来说,拥有全局数据会产生命名空间问题和代码重用问题。 如果回答满意,您介意接受吗? 很抱歉没有早点进行此操作.. 但我决定继续使用全局套接字变量.. 似乎是现在更容易的选择。以上是关于如何在反应服务器端渲染中正确处理 window=undefined 错误的主要内容,如果未能解决你的问题,请参考以下文章