如果请求了浏览器URL,则路由正常工作。
顺便说一句,location = $ {path}; 调用react renderToString函数时,表示组件错误的部分。
我正在查看Web Pack设置或其他内容,但找不到原因。救命!
// 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错误。 我真的很想解决。请帮忙。
答案 0 :(得分:0)
为什么未在SSR中定义window
在ssr上没有窗口的定义。因为window是基于浏览器的属性。
您需要采取一些措施来避免这种情况。例如
function goPage(path) {
console.log(`goPage..`);
if (window) {
console.log(window.location);
}
}
在服务器端,您可以通过此方法获取网址
req.url
// or
app.get('/users/:userId/books/:bookId', function (req, res) {
console.log(req.params)
}