繁体   English   中英

客户端路由更改后反应服务器端渲染未更新

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM