如何在 Next.js 中处理不受支持的 CSS 属性或在 Chakra-UI 中使用 @supports 指令

问题描述

我正在使用一个 React component,它根据是否支持 CSS backdrop-filter 指令使用不同的不透明度值:

background={(() => {
  const opacity = isBackdropFilterSupported() ? 0.75 : 0.98
  return (
    `linear-gradient(
      180deg,rgba(76,63,143,${opacity}) 62.76%,rgba(184,169,255,${opacity}) 100%
    )`
  )
})()}

问题是该站点是使用 Next.js 在服务器端生成的。 CSS.supports('backdrop-filter','blur(1px)') 在服务器上返回 false,因此无论客户端属性如何,该值始终为 false

一种解决方案是使用 CSS,如:

.drawer {
  --opacity: 0.75;
  background: linear-gradient(
    180deg,var(--opacity)) 62.76%,var(--opacity)) 100%
  );
}
@supports not (backdrop-filter: blur(1px)) {
  .drawer { --opacity: 0.98; }
}

这应该由客户端解释并避免服务器端渲染问题,但我没有发现关于如何将这种样式集成到它所构建的 Chakra-UI 中的迹象。

解决方法

我在原来的帖子中没有提到它,但我收到了一个错误,如:<?php $code = <<<EOD &lt;h4&gt;Show this title in HTML&lt;/h4&gt; &lt;p&gt;This paragraph must be in &lt;strong&gt;HTML&lt;/strong&gt; and this &lt;a href=&quot;&quot;&gt;Link&lt;/a&gt; too !&lt;/p&gt; &lt;?php echo &quot;Display this PHP code!&quot;; ?&gt; &lt;script&gt; alert(&quot;Don't pop-up please!&quot;); &lt;/script&gt; EOD; $code = str_replace("\n","<br>",$code); $code = str_replace(" ","&nbsp;",$code); $html = <<<EOD <h1>Escape HTML or Other Programming tags</h1> <p>This must be rendered without any problem</p> <p> <code style="display:block;background:rgb(230,230,230);padding:2%"> $code </code> <a href="">Link rendered</a> </p> EOD; echo $html;

事实证明,这意味着浏览器生成的 DOM 与 Next.js 生成的 DOM 不匹配。发生这种情况时,Next.js 放弃尝试重新水化文档,这就是我获得服务器渲染值的原因。

解决方案是使用钩子来确定组件何时被挂载(这只发生在客户端上)。那个钩子看起来像:

Prop id did not match. Server: "toggle--gxfg3t7xwo" Client: "toggle--ki0j10p2l"

然后不透明度确定变为:

export const useMounted = () => {
  // https://www.joshwcomeau.com/react/the-perils-of-rehydration/
  const [hasMounted,setHasMounted] = React.useState(false);
  React.useEffect(() => {
    setHasMounted(true);
  },[]);
  return hasMounted;
};

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...