第一次刷新了服务端,但是下一次,照常只改变了客户端,服务端没有改变。
例如,每次刷新或在浏览器中输入地址时,服务器也会更改并正常工作,但是如果我使用 react router 在客户端的页面之间切换,服务器不会更改。
有什么问题?
#server/server.js
import path from 'path';
import fs from 'fs';
import express from 'express';
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import { StaticRouter } from 'react-router-dom';
import App from '../src/App';
const PORT = 5000;
const app = express();
const router = express.Router();
app.use('/build', express.static('build'));
app.use((req, res, next) => {
if (/\.js|\.css|\.png|\.jpg|\.jpeg/.test(req.path)) {
res.redirect('/build' + req.path);
} else {
next();
}
})
app.get('*', (req, res) => {
const context = {};
const app = ReactDOMServer.renderToString(
<StaticRouter location={req.path} context={context}>
<App />
</StaticRouter>
);
const indexFile = path.resolve('./build/index.html');
fs.readFile(indexFile, 'utf-8', (err, data) => {
if (err) {
console.log("Something went wrong:", err);
return res.status(500).send("Oops, better luck next time!");
}
return res.send(data.replace('<div id="root"></div>', `<div id="root">${app}</div>`));
});
});
router.use(express.static(path.resolve(__dirname, '..', 'build'), { maxAge: '10d' }));
app.use(router);
app.listen(PORT, () => {
console.log(`SSR running on ${PORT}`);
});
#server/index.js
require('ignore-styles');
require('@babel/register')({
ignore: [/(node_module)/],
presets: ['@babel/preset-env', '@babel/preset-react'],
plugins: ['@babel/transform-runtime'],
});
require('./server');
#index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import * as serviceWorker from './serviceWorker';
import App from './App';
ReactDOM.hydrate(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
答案 0 :(得分:1)
您的服务器端渲染设置没有任何问题。这就是幕后发生的事情。
当您第一次键入并输入应用程序路由的 URL 或刷新浏览器选项卡时,它会访问服务器并在 {{1} 的帮助下加载在服务器端呈现的 index.html
文件}.
renderToString
然后查看 ReactDOMServer.renderToString(...)`
并将其添加到此框架 HTML 文件中(附加事件处理程序...等)。
请注意,您从 build 文件夹加载 index.html
并仅将 div 替换为 root 作为 ID。构建应用程序后,它添加 js 资源需要更改 index.html
(这些资源实际上是您为应用程序编写的前端逻辑),这是 DOM
呈现所必需的。如果您选中 client-side
,则它具有以下脚本标记来加载它们。
index.html
当您点击应用内的链接前往另一条路线时。它不会再次访问服务器,并开始执行从客户端包中附加的 js,正如我上面所说的。客户端 js 正确执行应用程序的路由。这就是它没有访问您的服务器的原因。这是 ...
<script src="/static/js/xxxxxxxxxxxxxxx.chunk.js">
...
的预期性质(在服务器端或客户端的行为相同)。之后,如果您刷新浏览器,它会再次从服务器加载 isomorphic web application
。