0

当前行为:

当有一个样式有条件地应用在浏览器上时,即使组件运行并且浏览器 props 被正确传入,来自服务器的样式也不会改变。从服务器发回的 html 保留在页面上,即使在传递新的基于浏览器的 props 的客户端上第一次渲染之后,组件仍继续显示服务器样式。这是在 nextjs 应用程序中,使用情感 11

我觉得这必须在某个地方进行介绍,但是我整天梳理了 SO、这些问题和 nextjs 问题,但没有发现任何描述确切问题的信息,也没有找到解决方法。

重现:Codesandbox 显示在服务器上具有一组样式的组件,然后在浏览器上时,应切换到另一组样式

https://codesandbox.io/s/cool-worker-meil8?file=/package.json:200-335

在服务器上,该框呈现为红色,因为 process.browser 为 false。在浏览器上,isBrowser 属性为 true,所以 js 运行后框应该是蓝色的。但是,尽管控制台日志显示样式化组件实际上确实在客户端上运行,并且 isBrowser true 并且背景颜色设置为蓝色,但该框仍然是红色(这不在沙箱中,但我拥有的唯一方法发现强制组件实际更改颜色是通过客户端导航或某种重新呈现组件的单独强制状态更新)。

预期行为:

我希望服务器发送回基于服务器版本的组件的 html/styles,然后在客户端上的第一次渲染之后,组件应该读取基于浏览器的样式并更新以匹配基于的样式浏览器道具。

环境信息:顺便说一下,这个codesandbox是使用codesandbox上nextjs的基础版本构建的。除了添加情感,我没有修改任何东西

以下是沙盒中的 deps:

“@emotion/react”:“11.4.1”

“@emotion/styled”:“11.3.0”

“下一个”:“最新”

“反应”:“17.0.2”

“反应域”:“17.0.2”

4

1 回答 1

0

似乎这不是一个特定于情感的问题,但实际上是由于较新版本的 react 不会区分 dom 水化,而是保留 html 同时仍生成正确的组件树(因此 js 运行,导致我的困惑,但 dom 不符合组件树显示的内容)。

如果其他人遇到这种情况,解决方案是使用这样的组件,它立即在服务器上渲染一个组件,然后在客户端通过在 useLayoutEffect 中设置 isMounted 状态触发渲染(这不会运行/重新渲染服务器)然后呈现客户端组件。总体思路如下所示:

https://github.com/vercel/next.js/discussions/14469

于 2021-09-03T21:15:43.550 回答