我有一个用Nextjs建立的网站,打破页面刷新或当用户访问网站直接到一个特定的路径,而不是根路由样式。例如https://vinnieography.web.app/contacts(网站链接,如果它看起来不错,尝试刷新,看看)
该网站托管在Firebase Functions上,使用Nextjs和Ant design components。
刷新前的网站屏幕截图
刷新后的网站屏幕截图(注意缺少导航)
导航并没有完全消失,但它变成了一个移动的导航的图标没有显示,但你得到一个下拉导航链接时,悬停在导航区。
我的下一个.config.js
const withCss = require('@zeit/next-css')
module.exports = withCss({
webpack: (config, { isServer }) => {
if (isServer) {
const antStyles = /antd\/.*?\/style\/css.*?/
const origExternals = [...config.externals]
config.externals = [
(context, request, callback) => {
if (request.match(antStyles)) return callback()
if (typeof origExternals[0] === 'function') {
origExternals[0](context, request, callback)
} else {
callback()
}
},
...(typeof origExternals[0] === 'function' ? [] : origExternals),
]
config.module.rules.unshift({
test: antStyles,
use: 'null-loader',
})
}
// Fixes npm packages that depend on `fs` module
config.node = {
fs: 'empty'
}
return config
},
distDir: "../../dist/client"
})
Nextjs、React和Antd的版本
"antd": "^3.24.2",
"next": "^9.0.2",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"@zeit/next-css": "^1.0.1",
7条答案
按热度按时间t98cgbkg1#
如果按照Material-UI NextJS示例中的建议修改应用程序没有帮助,您可以延迟加载组件。这样,您将强制它仅在加载客户端后创建样式。
禁用组件SSR的指南:https://nextjs.org/docs/advanced-features/dynamic-import#with-no-ssr
但是,请记住,组件将失去SSR的所有特权。
fsi0uk1n2#
我在使用带有MaterialUI的NextJS 9.4时遇到了这个问题。
每当样式被破坏时,我在控制台中收到此警告
警告:属性
className
不匹配。服务器:“多箱根多箱根5”客户端:跨度中的“MuiBox-root MuiBox-root-1”(由Styled(MuiBox)创建)我就是这么搞定的。
我们需要定制
document.js
和定制app.js
,如MaterialUI NextJS example中所述从此处复制
_document.js
和_app.js
https://github.com/mui-org/material-ui/tree/master/examples/nextjs/pages到
pages
文件夹从https://github.com/mui-org/material-ui/tree/master/examples/nextjs/src复制
theme.js
并将其放在某个位置,然后更新_document.js
和_app.js
中的导入链接现在样式应该起作用了。
rseugnpd3#
TLDR:您无法对Next.js使用基于移动的断点的条件呈现,因为服务器端呈现无法访问浏览器的维度。这解释了刷新时的视觉失真。使用服务器端呈现检测断点的唯一可靠方法是使用CSS媒体查询隐藏/取消隐藏移动组件。
根据此blog:
服务器既不能识别窗口也不能识别文档,这意味着设备,换句话说,不能检测强制属性(如客户端的视区尺寸)-因此它需要通过某种方式来推断它们,这意味着一种非常有限和不准确的响应方式。
例如,假设我们有一个使用matchMedia的应用程序(正如你可能知道的,这是一个Web API,它位于窗口的顶部)来根据视口的尺寸有条件地呈现组件。你希望服务器在没有窗口的情况下如何呈现标记,即使它是假设的多边形填充的,维度呢?2一旦初始呈现包含了一个有条件地受断点影响的响应组件,它将如何响应?
简单地说,这可能会导致服务器错误地呈现应用程序,最终导致部分水合来修补不匹配(即潜在的bug?)
ngynwnxp4#
为了可靠地执行服务器端渲染并让客户端包正常运行,你需要使用我们的babel插件。它通过给每个样式化组件添加一个确定性ID来防止校验和不匹配。参考工具文档了解更多信息。
bqjvbblv5#
使用动态导入ssr:false导入组件将解决此问题
f1tvaqid6#
这是因为服务器端呈现在呈现页面之前并不获取样式。样式化组件文档非常简短地提到了这一点,很容易被忽略。我们实际上要做的是将服务器端呈现的样式注入到头部,这样它就可以正确地呈现页面及其样式。Next.js中有你需要的文件,可以实现这一点。在Next中。你可以找到_document.js。
我在使用样式化组件时遇到过类似的问题,将样式化组件注册到_document. js中就解决了这个问题。
k2fxgqgv7#
我也遇到过同样的问题。但是我必须导入多个组件,然后根据条件返回。这是我的方法。我使用。then,因为动态是一个承诺。