[英]window is not defined server side rendering(react + express)
如果請求瀏覽器URL,路由工作正常。
順便說一句,位置 = ${path}; 調用 react renderToString function 時出現 Component An error 的部分。
我正在查看 web 包設置之類的,但找不到原因。 幫助!
// App.js
import React, {useState, useEffect} from 'react';
import moment from "moment";
import Header from "./components/header/Header";
import Footer from "./components/footer/Footer";
export default function App() {
const [time, setTime] = useState(null);
useEffect(() => {
console.log('use effect..');
setTime(moment().format('hh:mm:ss a'));
}, []);
return (
<div style={{height:'100%'}}>
<Header/>
<div style={{height:'100%'}}>
<h1>Sample App</h1>
<p>Current time is {time}</p>
</div>
<Footer/>
</div>
)
}
// Header.js
import React from 'react';
export default function Header() {
function goPage(path) {
console.log(`goPage..`);
console.log(window.location); // error
// window.location = path;
}
return (
<header style={{width: '100%', border: '1px dotted black'}}>
<div>
<span style={{padding: '4px'}}>My App |</span>
<span style={{padding: '4px', cursor: 'pointer'}}>Home</span>
<span style={{padding: '4px', cursor: 'pointer'}} onClick={goPage('/about')}>About</span>
</div>
</header>
)
}
server.js
const express = require('express');
const path = require('path');
import React from 'react';
import ReactDOMServer from 'react-dom/server';
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const config = require('../webpack.config.js');
const compiler = webpack(config);
import Router from '../routes/index';
import App from '../src/App';
import Html from "../src/Html";
const expressApp = express();
const port = process.env.PORT || 3000;
if (process.env.NODE_ENV != 'production') {
expressApp.use(webpackDevMiddleware(compiler, {
publicPath: '/'
}));
}
expressApp.use(express.static(path.join(__dirname, '')));
expressApp.get('*', (request, response) => {
console.log('request.. in express');
console.log(Router.match(request));
const component = ReactDOMServer.renderToString(Router.match(request));
const html = ReactDOMServer.renderToStaticMarkup(<Html
title="Sample Title"
description="Isomorphic web application sample"
body={component}
/>);
response.send(`<!DOCTYPE html>` + html);
});
expressApp.listen(port, () => {
console.log(`App is listening at http://localhost:${port}/`);
});
// Router
import React from 'react';
import App from "../src/App";
import NotFound from "../src/components/error/NotFound";
import Error from "../src/components/error/Error";
import About from "../src/components/about/About";
const routes = [
{name : 'home', path : '/', action : () => <App/>},
{name : 'about', path : '/about', action : () => <About/>},
{name : '404', path : '/404', action : () => <NotFound/>},
{name : '500', path : '/500', action : () => <Error/>},
];
export default {
match(location) {
console.log(location.path);
const route = routes.find(x => x.path === location.path);
if (route) {
try {
return route.action();
} catch (err) {
console.log('err');
return routes.find(x => x.path === '/500').action();
}
} else {
console.log('404');
return routes.find(x => x.path === '/404').action();
}
}
}
// webpack config
const path = require('path');
// plugin
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const MomentLocalesPlugin = require('moment-locales-webpack-plugin');
const nodeExternals = require('webpack-node-externals');
// SSR
const ssr = {
mode : 'development',
entry: './server/server.js',
output: {
path: path.join(__dirname, '/build'),
filename: "server.js",
},
target: 'node',
node: false,
externals: [nodeExternals()],
resolve: {
modules: ['node_modules']
},
module: {
rules: [
{
test: /(.js|.jsx)/,
exclude: /node_modules/,
include: [
path.join(__dirname, '/src'),
path.join(__dirname, '/routes/index.js'),
path.join(__dirname, '/server/server.js'),
],
use: {
loader: 'babel-loader'
}
},
]
},
plugins: [
new CleanWebpackPlugin({
cleanAfterEveryBuildPatterns: ['build']
})
],
};
// CSR
const csr = {
mode : 'development',
entry:'./client/client.js',
output: {
publicPath: '/',
path: path.join(__dirname, '/build'),
filename: 'client.js'
},
target: 'web',
module: {
rules: [
{
test: /(.js|.jsx)/,
exclude: /node_modules/,
include: [
path.join(__dirname, '/src'),
path.join(__dirname, '/routes/index.js'),
path.join(__dirname, '/client/client.js'),
],
use: {
loader: 'babel-loader'
}
},
]
},
// devtool: 'source-map',
plugins: [
new MomentLocalesPlugin({
localesToKeep: ['es-us', 'ru'],
}),
]
};
module.exports = [ssr, csr];
服務器由express組成,設置為babel7和webpack4。 如果你看 server.js 部分,你會在請求 URL 中得到對應的 react 組件。 如果在獲取的組件上調用renderToString(),則會出現window is not defined的錯誤。 我真的很想解決它。 請幫忙。
為什么 SSR 中沒有定義window
在 ssr 上沒有 window 的定義。 因為 window 是基於瀏覽器的屬性。
你需要做一些事情來避免這種情況。 例如
function goPage(path) {
console.log(`goPage..`);
if (window) {
console.log(window.location);
}
}
在服務器端,您可以通過此獲得 url
req.url
// or
app.get('/users/:userId/books/:bookId', function (req, res) {
console.log(req.params)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.