在 NextJs 中动态应用 TailwindCSS 样式时不会呈现

Bik*_*ath 1 reactjs next.js tailwind-css

为了使用 TailwindCSS 设置背景封面,我从 useEffect 内的 bookId(10 位数字)中提取了颜色。颜色会更新,组件会使用更新后的颜色值重新渲染,但渲染页面上的背景颜色仍然与其父 div 相同。

const colors = [
    'from-red-500',
    'from-orange-500',
    'from-yellow-500',
    'from-green-500',
    'from-cyan-500',
    'from-blue-500',
    'from-indigo-500',
    'from-violet-500',
    'from-purple-500',
    'from-pink-500',
]

function BgCover(props) {
    const [color, setColor] = useState(null)
    const router = useRouter()

    useEffect(() => {
        const id = router.query.bookId
        const index = id.slice(-1) //extract the index from bookId
        const bgColor = colors[index]
        setColor(bgColor)
    }, [])

    return (
        <Fragment>
            {color ? (
                <div className='flex-grow scrollbar-hide select-none relative'>
                    <div className={`bg-gradient-to-b ${color} to-black`}>
                        <section
                            className={`flex flex-col md:flex-row items-center justify-center p-4`}>
                            {props.children}
                        </section>
                    </div>
                </div>
            ) : (
                <p className='text-2xl'>Loading..</p>
            )}
        </Fragment>
    )
}
Run Code Online (Sandbox Code Playgroud)

但是,当我用颜色值(例如“from-red-500”)替换颜色变量时,背景颜色在渲染的页面中可见。

我还尝试用 getStaticProps 替换 useEffect 中的 setColor 代码,但代码的静态版本无法解决此问题(当使用颜色变量时)。

谢谢你的帮助。

小智 7

这是 tailwindcss 和动态类的一个已知问题,因为该类是在渲染后应用的,因此它的效果不会由 tailwind 生成,除非其中存在另一个与静态类具有相同类的元素。

因此,您可以使用顺风“安全列表”来解决此问题。在 tailwind.config 中,定义一个安全列表数组,其中包含需要生成且代码中不作为静态类存在的所有 tailwind 类。

tailwind.config.js:

module.exports = {
  content: [
    './pages/**/*.{html,js}',
    './components/**/*.{html,js}',
  ],
  safelist: [
    'from-red-500',
    'from-orange-500',
    'from-yellow-500',
    'from-green-500',
    'from-cyan-500',
    'from-blue-500',
    'from-indigo-500',
    'from-violet-500',
    'from-purple-500',
    'from-pink-500',
  ]
  // ...
}
Run Code Online (Sandbox Code Playgroud)

现在,此类将始终生成,因此当您动态应用它们时,它们会相应地更改。

请注意,添加到安全列表后需要重新启动服务器。

来源

另一个手动解决方案是创建一个隐藏元素并向其中添加所有需要的类,这样即使您在渲染后动态获取它们,它们也会生成

<div className="hidden from-red-500"></div>
Run Code Online (Sandbox Code Playgroud)

但我认为安全列表更好