1、原因
ssr 會在後端執行元件的 componentWillMount 以及在它這個生命周期之前的生命周期
也就是說 ssr 階段是不會執行 componentDidMount 方法的
當你在 componentWillMount 之前當生命周期裡面調用 window / localstorage 全局對象的時候,
它其實是在伺服器上面執行等,因為 window / localstorage 是浏覽器的屬性對象。
是以在 伺服器端 跑的時候,就會出現沒有定義的錯誤。
2、解決方案
個人覺得可以把這些浏覽器的屬性重新封裝以便使用。
例如:
let targetWin = null
if(window) targetWin = window
var proxyWindow = new Proxy(targetWin,{
get: function (target, key, receiver) {
if(!targetWin) {
return Reflect.get({nothing:function () {}}, 'nothing', receiver);
}
return Reflect.get(target, key, receiver);
}
});
export default proxyWindow
沒有在項目中試過,不過我覺得這是一個完美解決方案。
上面是用了 es6 的 proxy 做代理。
當 window 不存在時候,如果調用了 window 上面的方法或者屬性就會執行 nothing 這個方法。
也就是說 在伺服器渲染的時候 不會找不到 window ,而會執行 nothing 方法。
這樣就不會報錯了。
這裡的話,以後使用 window 的對象的話,就需要引用這個子產品。
以此類推,localstorage / location 等都可以用此類方法實作了。