【问题标题】:React server side rendering is not updating after client side route change客户端路由更改后反应服务器端渲染未更新
【发布时间】:2021-07-31 01:08:30
【问题描述】:

第一次刷新服务端,但下一次照常只改变客户端,服务端不变。

例如,每次在浏览器中刷新或键入地址时,服务器也会更改并正常工作,但是如果我在客户端使用 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')
);

【问题讨论】:

    标签: javascript node.js reactjs express server-side-rendering


    【解决方案1】:

    您的服务器端渲染设置没有问题。这就是幕后发生的事情。

    当您第一次键入并输入应用程序路由的 URL 或刷新浏览器选项卡时,它会访问服务器并在 renderToString 的帮助下加载在服务器端呈现的 index.html 文件。

    ReactDOMServer.renderToString(...)`
    

    然后index.html 被查看并被水合(附加事件处理程序...等)到这个骨架 HTML 文件。

    请注意,您从 build 文件夹加载 index.html 并仅将 div 替换为 root 作为 id。构建应用程序后,它添加 js 资源需要更改 DOM(这些资源实际上是您为应用程序编写的前端逻辑),这是 client-side 渲染所必需的。如果您检查index.html 它有以下脚本标签来加载它们。

    ...
    <script src="/static/js/xxxxxxxxxxxxxxx.chunk.js">
    ...
    

    当您通过单击应用内的链接转到另一条路线时。它不会再次访问服务器并开始执行从客户端捆绑包附加的 js,正如我上面所说的。客户端 js 正确执行应用程序的路由。这就是为什么它没有击中您的服务器。这是isomorphic web application 的预期性质(在服务器端或客户端的行为相同)。之后,如果您刷新浏览器,再次从服务器加载index.html

    【讨论】:

    • 我到底应该怎么做?请帮助提供更多详细信息。谢谢。
    • @behi,我认为您为 SEO 目的或提高网站性能进行了服务器渲染设置。您做得对,我对您提出的问题进行了解释。
    • @behi,如果这消除了您的疑虑,您可以将其标记为答案吗?谢谢!
    猜你喜欢
    • 2015-09-06
    • 2012-01-17
    • 2015-05-09
    • 2017-12-29
    • 2016-05-26
    • 2018-02-05
    • 2018-01-05
    • 2021-08-27
    • 2016-02-05
    相关资源
    最近更新 更多