Reactjs 在SSR React应用程序中刷新或手动键入URL会更改类名

Reactjs 在SSR React应用程序中刷新或手动键入URL会更改类名,reactjs,sass,react-router,server-side-rendering,Reactjs,Sass,React Router,Server Side Rendering,该应用程序最初由CRA制作,并转换为SSR。该应用程序工作正常,但只有当我刷新应用程序或手动键入某个页面的URL时,问题才会出现。中间div的类名随后被重写为基本路由的中间div的类名 例如,它的变化如下: <div id="root"> <div class="header">..</div> <div class="newlist">..</div> <div class="footer">..<

该应用程序最初由CRA制作,并转换为SSR。该应用程序工作正常,但只有当我刷新应用程序或手动键入某个页面的URL时,问题才会出现。中间div的类名随后被重写为基本路由的中间div的类名

例如,它的变化如下:

<div id="root">
   <div class="header">..</div>
   <div class="newlist">..</div>
   <div class="footer">..</div>   
</div>

..
..
..   
为此:

<div id="root">
   <div class="header">..</div>
   <div class="main-flex-container">..</div>
   <div class="footer">..</div>   
</div>

..
..
..   
有关更多信息,请参见我的src/index.js:

import React, { useEffect } from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { BrowserRouter } from 'react-router-dom';
import configureStore, { history } from './redux/store/index';
import AppRouter from './routers/AppRouter';
import './styles/styles.scss';

const store = configureStore();

require('dotenv').config();

const isServer = typeof window !== 'undefined';

if (isServer) {
  ReactDOM.hydrate(
    <Provider store={store}>
      <BrowserRouter>
        <AppRouter />
      </BrowserRouter>
    </Provider>,
    document.getElementById('root'),
  );
}
import React,{useffect}来自“React”;
从“react dom”导入react dom;
从'react redux'导入{Provider};
从“react router dom”导入{BrowserRouter};
从“./redux/store/index”导入configureStore,{history};
从“./路由器/AppRouter”导入AppRouter;
导入“./styles/styles.scss”;
const store=configureStore();
require('dotenv').config();
const isServer=窗口类型!='未定义';
如果(isServer){
水合物(

到GitHub上的项目。

因此,这里的问题的症结似乎是,当在服务器上呈现时,路由器没有像我们预期的那样基于url呈现正确的组件

发生的事情并不是类名发生了更改,而是我们实际上总是呈现根页面,然后在您有机会在inspector中查看内容之前,react用客户端上的“new task”页面替换内容

小结:在express中对路径使用
app.use
时,我们正在指定路径上装载express中间件,express将删除“装载点”从提供给中间件的
req.url
中。在其他解决方案中,我们可以使用
req.originalUrl
来获取实际的url。
req.originalUrl
是express提供的一个属性,它提供了任何中间件更改之前的url


让我们调查一下

如果我们提取将应用程序呈现为单独变量的代码并记录该变量,我们将看到记录的HTML字符串是带有“New List”按钮的页面

const renderapp=ReactDOMServer.renderToString(

我看不到
req.url
的文档,但是这里有一个有用的框来解释为什么会这样(
req.url
来自节点的http模块)

记录
req.originalUrl
也只是为了看看这对我们来说是什么,当然:

original URL: /l/new
URL: /
req.originalUrl
有我们需要的

在这一点上,我四处搜索了一些参考资料来解释为什么在我们的例子中
req.url
可能是
/
,结果发现这是因为:

当我们使用
app.use
时,我们是在指定路径上安装一个express中间件,而不是设置一个路由处理程序(即
app.get
或类似)并且MediLeWARS从它们自己的URL中删除它们所安装的路径,因为它们考虑了它们的<代码>根/代码>。当我们指定要安装在“代码>/*”的中间件时,通配符匹配所有路由,并且删除整个URL。< /P> 换句话说,我们可以通过几种不同的方式解决此问题:

  • 保持原样,但改用
    req.originalUrl
  • app.use
    app.use((req,res,next)=>{/*您的代码*/})
    )中删除路径
  • app.use
    更改为
    app.get

  • 希望这会有所帮助!

    因此,这里的问题症结似乎在于,在服务器上呈现时,路由器没有按照我们预期的那样基于url呈现正确的组件

    发生的事情并不是类名发生了更改,而是我们实际上总是呈现根页面,然后在您有机会在inspector中查看内容之前,react用客户端上的“new task”页面替换内容

    小结:在express中对路径使用
    app.use
    时,我们正在指定路径上装载express中间件,express将删除“装载点”从提供给中间件的
    req.url
    中。在其他解决方案中,我们可以使用
    req.originalUrl
    来获取实际的url。
    req.originalUrl
    是express提供的一个属性,它提供了任何中间件更改之前的url


    让我们调查一下

    如果我们提取将应用程序呈现为单独变量的代码并记录该变量,我们将看到记录的HTML字符串是带有“New List”按钮的页面

    const renderapp=ReactDOMServer.renderToString(
    

    我看不到
    req.url
    的文档,但是这里有一个有用的框来解释为什么会这样(
    req.url
    来自节点的http模块)

    记录
    req.originalUrl
    也只是为了看看这对我们来说是什么,当然:

    original URL: /l/new
    URL: /
    
    req.originalUrl
    有我们需要的

    在这一点上,我四处搜索了一些参考资料来解释为什么在我们的例子中
    req.url
    可能是
    /
    ,结果发现这是因为:

    当我们使用
    app.use
    时,我们是在指定路径上安装一个express中间件,而不是设置一个路由处理程序(即
    app.get
    或类似)并且MediLeWARS从它们自己的URL中删除它们所安装的路径,因为它们考虑了它们的<代码>根/代码>。当我们指定要安装在“代码>/*”的中间件时,通配符匹配所有路由,并且删除整个URL。< /P> 换句话说,我们可以通过几种不同的方式解决此问题:

  • 保持原样,但改用
    req.originalUrl
  • app.use
    app.use((req,res,next)=>{/*您的代码*/})
    )中删除路径
  • app.use
    更改为
    app.get

  • 希望这能有所帮助!

    回答得很好,Kim!很高兴你能深入了解这一点。我需要在我的SSR上做更多的工作
    URL: /
    
    original URL: /l/new
    URL: /