【问题标题】:How to conditionally render a component in Next.js without caching CSS styles?如何在不缓存 CSS 样式的情况下有条件地在 Next.js 中渲染组件?
【发布时间】:2021-09-15 13:11:15
【问题描述】:

我是 Next.js 的新手,并不完全了解缓存的功能。

给出以下简化示例:

根据当前分钟是偶数还是奇数,呈现组件 Test1Test2 的索引页面:

import { Test2 } from '@src/components/test2'
import React from 'react'

const conditionallyChooseComponent = () => {
  const d = new Date()
  if (d.getMinutes() % 2 === 0) return <Test1 />
  else return <Test2 />
}

export default function Home() {
  return <div>{conditionallyChooseComponent()}</div>
}

并具有以下组件。测试1:


export const Test1 = () => {
  const d = new Date()

  return (
    <div className={`${utilStyles.redContainer}`}>
      <h1>It's {d.toISOString()} and I'm Test1 component. My background should be red</h1>
    </div>
  )
}

和测试2:


export const Test2 = () => {
  const d = new Date()

  return (
    <div className={`${utilStyles.blueContainer}`}>
      <h1>It's {d.toISOString()} and I'm Test2 component. My background should be blue</h1>
    </div>
  )
}

还有这个 CSS:

.redContainer {
  background-color: red;
}

.blueContainer {
  background-color: blue;
}

在通过编译代码构建和提供代码执行代码时,背景颜色被缓存。当使用yarn dev 运行时,它工作得很好。

这是意想不到的结果:

Screenshot with Test1 component being rendered with blue background

PS:我使用getInitialProps 来防止 Next.js 缓存该页面中的任何内容,但对于我的实际用例,该选项无效,因为我需要计算渲染条件在客户端,因为它将取决于浏览器的本地日期。

【问题讨论】:

    标签: css typescript caching next.js


    【解决方案1】:

    要使其正常工作,您需要添加一些客户端代码(通过useEffect),以便 React 组件每分钟(左右)更新一次。有趣的是,这并不像听起来那么简单,甚至 Dan Abramov has published a long post explaining why things such as setInterval may not work intuitively with React(特别是使用 React Hooks)。

    假设您使用 Dan 在上面的文章中解释的自定义钩子,这应该可以工作:

    export default function Home() {
      const [date, setDate] = useState(new Date());
    
      useInterval(() => {
        // this will update the component's date every second
        setDate(new Date()); 
      }, 1000);
    
      return <div>{date.getMinutes() % 2 === 0 ? <p>Test 1</p> : <p>Test 2</p>}</div>;
    }
    

    请注意,您的代码示例仅在 Next 尝试在服务器端呈现您的页面时执行一次 conditionallyChooseComponent

    【讨论】:

      【解决方案2】:

      Next 会自动缓存所有不依赖外部数据的静态页面,也许你可以实现 useEffect 来更新你的日期变量或使用一个简单的状态,所以它应该按照你期望的方式工作

      https://nextjs.org/docs/basic-features/pages#static-generation-without-data

      【讨论】:

      • 感谢 @user8684881 抽出时间回复 :) 不幸的是,我确实尝试使用 useEffectuseState 但它仍在缓存中。 export default function Home() { const [pair, setPair] = useState(isEven(new Date())) useEffect(() =&gt; { setPair(isEven(new Date())) }, [pair]) if (pair) return &lt;Test1 /&gt; return &lt;Test2 /&gt; }这是你建议的吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-23
      • 1970-01-01
      • 2022-01-19
      • 2021-09-22
      • 2016-07-13
      • 2021-10-23
      • 2020-08-18
      相关资源
      最近更新 更多