Reactjs 在SSR React应用程序中刷新或手动键入URL会更改类名
该应用程序最初由CRA制作,并转换为SSR。该应用程序工作正常,但只有当我刷新应用程序或手动键入某个页面的URL时,问题才会出现。中间div的类名随后被重写为基本路由的中间div的类名 例如,它的变化如下: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">..<
<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: /