[英]React server side rendering is not updating after client side route change
第一次刷新服务端,但下一次照常只改客户端,服务端不变。
例如,每次在浏览器中刷新或键入地址时,服务器也会发生变化并正常工作,但如果我使用 react 路由器在客户端的页面之间切换,服务器不会发生变化。
问题是什么?
#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')
);
您的服务器端渲染设置没有任何问题。 这就是幕后发生的事情。
当您第一次键入并输入 URL 以获取应用程序的路由或刷新浏览器选项卡时,它会访问服务器并加载index.html
文件,并借助renderToString
在服务器端呈现。
ReactDOMServer.renderToString(...)`
然后查看index.html
并将其水合(附加事件处理程序......等)到这个骨架 HTML 文件。
请注意,您从构建文件夹加载index.html
并仅将 div 替换为 root 作为 id。 在构建应用程序后,它添加了需要更改DOM
的 js 资源(这些资源实际上是您为应用程序编写的前端逻辑),这是client-side
渲染所必需的。 如果您检查index.html
它有以下脚本标签来加载它们。
...
<script src="/static/js/xxxxxxxxxxxxxxx.chunk.js">
...
当您通过单击应用程序内的链接 go 到另一条路线时。 它不会再次访问服务器并开始执行从客户端捆绑包附加的 js,正如我上面所说的。 客户端 js 正确执行应用程序的路由。 这就是为什么它没有击中您的服务器。 这是isomorphic web application
的预期性质(在服务器端或客户端的行为相同)。 之后,如果您刷新再次从服务器加载index.html
的浏览器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.