I have a simple project where I am exposing the built FE project (which has React and ChakraUI) through an express server. Things go well until I import a Box component from chakra. It gets rendered through SSR, but without any styling. From what I understand, the classNames from the client are not in sync with the ones on the server. Is there any way I can fix this?
我有一个简单的项目,其中我通过一个Express服务器公开了构建的FE项目(它有Reaction和ChakraUI)。在我从脉轮导入Box组件之前,一切都很顺利。它通过SSR呈现,但没有任何样式。据我所知,来自客户端的类名称与服务器上的类名称不同步。我有什么办法可以解决这个问题吗?
Error message: Prop className
did not match. Server: "null" Client: "css-1xip3bv".
错误消息:属性类名称不匹配。服务器:“空”客户端:“css-1xip3bv”。
SSR part on the server:
服务器上的SSR部分:
// ssr
const renderFullPage = (html, styles) => {
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>What is the HTTP code?</title>
${styles}
<script defer src="./bundle.js"></script>
</head>
<body>
<div id="app">${html}</div>
</body>
</html>`;
}
app.use('^/$', (req, res) => {
const html = renderToString(
<CacheProvider value={cache}>
<ChakraBaseProvider theme={theme}>
<CSSReset />
<App />
</ChakraBaseProvider>
</CacheProvider>,
)
const emotionChunks = extractCriticalToChunks(html)
const emotionCss = constructStyleTagsFromChunks(emotionChunks)
res.contentType('text/html')
res.status(200)
res.send(renderFullPage(html, emotionCss))
})
index.js on the FE side and the App component:
FE端和App组件上的index.js:
index.js
Index.js
import * as React from 'react'
import { hydrateRoot, createRoot } from 'react-dom/client'
import { ChakraBaseProvider, CSSReset, extendBaseTheme } from '@chakra-ui/react'
import { CacheProvider } from '@emotion/react'
import App from './App'
import { cache } from './createCache'
const theme = extendBaseTheme({
colors: {
red: '#C53030',
}
})
const container = document.getElementById('app')
hydrateRoot(
container,
<CacheProvider value={cache}>
<ChakraBaseProvider theme={theme}>
<CSSReset />
<App />
</ChakraBaseProvider>
</CacheProvider>,
)
App.jsx
App.jsx
import React from 'react'
import { Box } from '@chakra-ui/react'
import NumberInput from './components/NumberInput'
const App = () => {
const isClient = typeof window !== "undefined";
const Component = isClient ? Box : 'div'
return (
<>
<Component bg="red">
<h1>What is the HTTP code?</h1>
</Component>
<div>"What is the HTTP code?" is a project designed to make people's life easier when dealing
with HTTP response status codes. The purpose is to create a lightweight, reliable and easy
to use tool that's accesible to everyone, whether you're a seasoned software developer or a
beginner just starting out. The HTTP response status codes are described in the internet
standard RFC 9110.
</div>
<NumberInput />
</>
)
}
export default App
I tried changing the babel file in a few ways, although I am not sure I'm doing it well, my current babel settings are these:
我试着用几种方法更改了巴别塔文件,尽管我不确定我是否做得很好,但我目前的巴别塔设置如下:
require('@babel/register')({
ignore: [/(node_modules)/],
presets: [
'@babel/preset-env',
'@babel/preset-react',
],
plugins: [[
"@emotion",
{
"sourceMap": true,
"autoLabel": "dev-only",
"labelFormat": "[local]",
"cssPropOptimization": true,
"ssr": true
}
]]
})
I am expecting the styling on the server to be in sync with the one on the client. For example if I add a red background to the Box component, it should be red, not white as it shows up right now.
我期待服务器上的样式与客户端上的同步。例如,如果我向Box组件添加一个红色背景,它应该是红色的,而不是现在显示的白色。
Any help is very much appreciated,
Thank you.
非常感谢您的帮助,谢谢。
更多回答
我是一名优秀的程序员,十分优秀!