Nextjs 生产应用程序上的页面刷新中断样式

Arc*_*oob 18 reactjs next.js antd

我有一个用 Nextjs 构建的网站,它在页面刷新时或当用户直接访问网站到特定路由而不是根路由时打破样式。例如https://vinnieography.web.app/contacts(站点链接如果看起来不错,请尝试刷新并查看)

该网站托管在 Firebase Functions 上,并使用 Nextjs 和Ant 设计组件

刷新前的网站截图

刷新前的网站截图

刷新后的网站截图(注意缺少的导航)

导航并没有完全丢失,但它变成了一个移动导航,它的图标没有显示,但是当你在导航区域周围悬停时,你会得到一个带有导航链接的下拉菜单。

刷新后的网站截图

我的 next.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"
})
Run Code Online (Sandbox Code Playgroud)

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",
Run Code Online (Sandbox Code Playgroud)

kir*_*nvj 7

我在使用带有 MaterialUI 的 NextJS 9.4 时遇到了这个问题。

每当样式损坏时,我都会在控制台中收到此警告

警告:道具className不匹配。服务器:“MuiBox-root MuiBox-root-5” 客户端:跨度中的“MuiBox-root MuiBox-root-1”(由 Styled(MuiBox) 创建)

在此处输入图片说明

这就是我固定的方式。

我们需要像 MaterialUI NextJS 示例中提到的customdocument.js和 customapp.js

复制_document.js_app.js从这里https://github.com/mui-org/material-ui/tree/master/examples/nextjs/pages

在此处输入图片说明

pages文件夹

在此处输入图片说明

复制theme.jshttps://github.com/mui-org/material-ui/tree/master/examples/nextjs/src 某处放置和更新在进口环节_document.js_app.js

样式现在应该可以工作了。


zil*_*nas 5

如果按照 Material-UI NextJS 示例中的建议修改应用程序没有帮助,您可以延迟加载您的组件。这样,您将仅在加载客户端后强制它创建样式。

为组件禁用 SSR 的指南:https : //nextjs.org/docs/advanced-features/dynamic-import#with-no-ssr

import dynamic from 'next/dynamic'

export const ComponentWithNoSSR = dynamic(() => import('./Component'), {
  ssr: false,
})
Run Code Online (Sandbox Code Playgroud)

但是,请记住,该组件将失去 SSR 的所有特权。


Emb*_*ugs 5

TLDR:您不能在 Next.js 中使用基于移动断点的条件渲染,因为服务器端渲染无法访问浏览器的尺寸。这解释了刷新时的视觉扭曲。检测服务器端渲染断点的唯一可靠方法是使用 CSS 媒体查询来隐藏/取消隐藏移动组件。

\n

根据这个博客

\n
\n

服务器无法识别窗口和文档。换句话说,这意味着设备无法检测强制性属性(例如客户端的视口尺寸) - 因此它需要以某种方式推断它们,这意味着一种非常有限且不准确的响应方式。

\n

例如,假设我们\xe2\x80\x99有一个应用程序,它使用matchMedia\n(您可能知道,这是一个到达窗口顶部的Web API)来根据视口\n尺寸有条件地渲染组件。您希望服务器如何在没有窗口的情况下呈现标记\n,即使它\xe2\x80\x99s 假设以某种方式填充,\n尺寸又如何呢?一旦初始渲染包含有条件地受断点影响的响应组件,它将如何响应?

\n

简而言之 - 这可能会导致服务器错误地渲染我们的应用程序,最终导致部分水合,从而修补不匹配的情况(即潜在的错误?)。

\n
\n