ReactDOM.renderToString sessionStorage is not defined, window is not defined

匿名 (未验证) 提交于 2019-12-03 10:24:21

问题:

I have an application with webpack configured as a module bundler and babel as my js compiler. all on a node engine. I stetted up that when I run npm run dev the following flow will happen:

The webpack-dev-server.js will run. the file is the following:

const Express = require('express'); const webpack = require('webpack'); const webpackConfig = require('./dev.config'); const compiler = webpack(webpackConfig);  const host = 'localhost'; const port = 8080; const serverOptions = {   contentBase: `http://${host}:${port}`,   quiet: true,   noInfo: true,   hot: true,   inline: true,   lazy: false,   publicPath: webpackConfig.output.publicPath,   headers: { 'Access-Control-Allow-Origin': '*' },   stats: { colors: true }, };  const app = new Express();  app.use(require('webpack-dev-middleware')(compiler, serverOptions)); app.use(require('webpack-hot-middleware')(compiler));  app.listen(port, function onAppListening(err) {   if (err) {     console.error(err);   } else {     console.info('==> Webpack development server listening on port %s', port);   } }); 

Then the server.js

require('./../server.babel'); const path = require('path'); const WebpackIsomorphicTools = require('webpack-isomorphic-tools'); const rootDir = path.resolve(require('../server/config').rootDir);  global.__CLIENT__ = false; global.__SERVER__ = true; global.__DEVELOPMENT__ = process.env.NODE_ENV !== 'production';  if (__DEVELOPMENT__) {   if (!require('piping')({     hook: true,     ignore: /(\/\.|~$|\.json|\.scss$)/i   })) {     return;   } }  global.webpackIsomorphicTools = new WebpackIsomorphicTools(require('../webpack/webpack-isomorphic-tools'))   .development(__DEVELOPMENT__)   .server(rootDir, () => {     require('../server/server');   }); 

express and React rendering:

import 'babel-polyfill'; // Server import express from 'express'; import session from 'express-session'; import cookieParser from 'cookie-parser'; // React import React from 'react'; import ReactDOM from 'react-dom/server'; import createHistory from 'react-router/lib/createMemoryHistory'; import { match } from 'react-router'; // Redux import { Provider } from 'react-redux'; import { ReduxAsyncConnect, loadOnServer } from 'redux-connect'; import { syncHistoryWithStore } from 'react-router-redux'; import path from 'path'; import csurf from 'csurf'; import bodyParser from 'body-parser'; // Relative imports import Html from '../shared/html'; import proxy from './proxy'; import createStore from '../shared/redux/create'; import { staticPath } from './config'; import { getRoutes } from '../shared/routes';  require('dotenv').config({   path: path.resolve(__dirname, '../.env'), });  const SERVER_PORT = process.env.SERVER_PORT; const APP_SECRET = process.env.APP_SECRET; const API_PORT = process.env.API_PORT; const API_HOST = process.env.API_HOST;  function renderPage({ renderProps, store, res, client, csrfToken }) {   loadOnServer({ ...renderProps, store, helpers: { client } })     .then(() => {       const component = (         <Provider store={store} key="provider">           <ReduxAsyncConnect {...renderProps} />         </Provider>       );       res.status(200);       res.send('<!doctype html>\n' +         ReactDOM.renderToString(           <Html             assets={webpackIsomorphicTools.assets()}             component={component}             csrfToken={csrfToken}             store={store}           />,         ),       );     })     .catch((err) => {       console.error(err.stack);     }); }   const app = express(); const csrf = csurf();  // express middlewares // app.use(favicon(path.resolve(__dirname, '../static/favicon.ico'))); @TODO favicon @ilanus app.use(bodyParser.json()); app.use(express.static(staticPath)); app.use(cookieParser(APP_SECRET)); app.use(session({   secret: APP_SECRET,   saveUninitialized: true,   resave: true, })); app.use(csrf); app.use('/api', (req, res) => {   if (!req.xhr) res.redirect('/');   proxy.web(req, res, { target: `http://${API_HOST}:${API_PORT}` }); }); app.use((req, res) => {   const csrfToken = req.csrfToken();   if (__DEVELOPMENT__) {     // Do not cache webpack stats: the script file would change since     // hot module replacement is enabled in the development env     webpackIsomorphicTools.refresh();   }   const memoryHistory = createHistory(req.originalUrl);   const store = createStore({}, memoryHistory);   const history = syncHistoryWithStore(memoryHistory, store);   match({ history, routes: getRoutes(store), location: req.originalUrl },     (error, redirectLocation, renderProps) => {       if (redirectLocation) {         res.redirect(redirectLocation.pathname + redirectLocation.search);       } else if (error) {         console.error('ROUTER ERROR:', error);         res.status(500);       } else if (renderProps) {         renderPage({ renderProps, store, res, csrfToken });       } else {         res.status(404).send('Not found');       }     }); });  app.use((err, req, res) => {   if (err === 'EBADCSRFTOKEN') {     res.status(403);     res.send('invalid csrf token');   } else {     res.status(500);     res.send('Oops, internal server error');   } });  app.listen(SERVER_PORT, (error) => {   if (error) {     console.error(error);   } else {     console.info(`App started listening on port ${SERVER_PORT}`);   } }); 

Now whenever I try to console.log('window', window, 'sessionStorage', sessionStorage); within a render() function or componentDidMount() of a react component I end up with: sessionStorage is not defined, window is not defined errors. I guess that's because I am running the stack on the server-side and those are not available there what am I missing?

回答1:

You just need a function instead of accessing window and window properties directly, e g

function globalObj(){     const isNode = typeof process === 'object' && process.versions && !!process.versions.node;      return isNode ? global : window;  } 

You can the access sessionStorage etc from there in a universal way without errors

globalObj()["sessionStorage"] 

I hope that helps.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!