TailwindCSS 样式在 NextJs 中动态应用时未呈现。

huangapple go评论59阅读模式
英文:

TailwindCSS styles not rendered when applied dynamically in NextJs

问题

为了使用TailwindCSS设置背景封面,我已经从bookId(10位数字)中提取了颜色,然后在useEffect内部更新了颜色。颜色得到更新,组件重新渲染,但渲染页面上的背景颜色仍然与其父级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) // 从bookId中提取索引
        const bgColor = colors[index]
        setColor(bgColor)
    }, [])

    return (
        <>
            {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'>加载中...</p>
            )}
        </>
    )
}

但是当我用一个颜色值(比如'from-red-500')替换color变量时,渲染页面上的背景颜色可见。

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

感谢任何帮助。

英文:

To set the background cover using TailwindCSS I have extracted the color from bookId (10 digit number) inside useEffect. The color gets updated and component re-renders with the updated color value but the background color on the rendered page is still the same of its parent div.

const colors = [
	&#39;from-red-500&#39;,
	&#39;from-orange-500&#39;,
	&#39;from-yellow-500&#39;,
	&#39;from-green-500&#39;,
	&#39;from-cyan-500&#39;,
	&#39;from-blue-500&#39;,
	&#39;from-indigo-500&#39;,
	&#39;from-violet-500&#39;,
	&#39;from-purple-500&#39;,
	&#39;from-pink-500&#39;,
]

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

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

	return (
		&lt;Fragment&gt;
			{color ? (
				&lt;div className=&#39;flex-grow scrollbar-hide select-none relative&#39;&gt;
					&lt;div className={`bg-gradient-to-b ${color} to-black`}&gt;
						&lt;section
							className={`flex flex-col md:flex-row items-center justify-center p-4`}&gt;
							{props.children}
						&lt;/section&gt;
					&lt;/div&gt;
				&lt;/div&gt;
			) : (
				&lt;p className=&#39;text-2xl&#39;&gt;Loading..&lt;/p&gt;
			)}
		&lt;/Fragment&gt;
	)
}

But when I replace the color variable with a color value (say 'from-red-500') then the background color is visible in the rendered page.

I have also tried to replace the setColor code in useEffect with getStaticProps but the static version of the code cannot solve this problem (when color varible is used).

Thanks for any help.

答案1

得分: 4

这是与tailwindcss和动态类相关的已知问题,因为类是在渲染之后应用的,所以它的效果不会被tailwind生成,除非另一个元素具有与静态类相同的类。

所以,你可以使用tailwind的"safelist"来解决这个问题。
在你的tailwind.config中,定义一个safelist数组,其中包含所有你需要生成的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',
  ]
  // ...
}

现在这些类将始终被生成,因此当你动态应用它们时,它们将相应更改。

请注意,添加到safelist后,你需要重新启动服务器。

来源

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

<div className="hidden from-red-500"></div>

但我认为safelist更好。

英文:

This is a known issue with tailwindcss and dynamic classes, because the class is applied after rendering so its effect won't be generated by tailwind unless there was another element in that had the same class as a static class.

So, you can use tailwind "safelist" to resolve this.
In your tailwind.config, define a safelist array of all tailwind classes that you need to be generated and that don't exist in your code as static classes.

tailwind.config.js:

module.exports = {
  content: [
    &#39;./pages/**/*.{html,js}&#39;,
    &#39;./components/**/*.{html,js}&#39;,
  ],
  safelist: [
    &#39;from-red-500&#39;,
    &#39;from-orange-500&#39;,
    &#39;from-yellow-500&#39;,
    &#39;from-green-500&#39;,
    &#39;from-cyan-500&#39;,
    &#39;from-blue-500&#39;,
    &#39;from-indigo-500&#39;,
    &#39;from-violet-500&#39;,
    &#39;from-purple-500&#39;,
    &#39;from-pink-500&#39;,
  ]
  // ...
}

Now this classes will always get generated so when you apply them dynamically, they will change accordingly.

Note that you need to restart your server after adding to the safelist.

Source

Another manual solution is to make a hidden element and add all your needed classes to it so they will be generated even if you get them dynamically after render

&lt;div className=&quot;hidden from-red-500&quot;&gt;&lt;/div&gt;

but safelist is better I think

huangapple
  • 本文由 发表于 2023年2月14日 02:49:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75440072.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定