包阅导读总结
1. `CSS-in-JS`、`React Server Components`、`Linaria`、`Styled-Components`、`服务器渲染`
2. 本文主要探讨了随着 React 生态演变,尤其是 Next.js 转向“服务器优先”方式后,CSS-in-JS 方案面临挑战。介绍了 RSC 范式前后的变化,解释了传统 CSS-in-JS 库不兼容的原因,并推荐了替代方案 Linaria 及其工作原理。
3.
– CSS-in-JS 与 React Server Components
– 传统 CSS-in-JS 库如 Emotion 和 styled-components 与新的 React 范式不兼容
– 维护者是开源贡献者,更新库以适应变化任务艰巨
– React Server Components(RSC)范式
– 之前在服务器和客户端渲染组件,存在重复工作
– 现在默认组件仅在服务器渲染,减少/消除客户端 JavaScript
– 可通过 use client 指令启用客户端特定方法
– CSS-in-JS 不兼容 RSC 的原因
– 传统库在客户端运行时做大量工作,而 RSC 主要在服务器渲染
– 解决方案
– Linaria 将工作转移到构建阶段,使用类似 styled-components 的 API
– 构建时创建 CSS 模块文件,无需客户端 JavaScript
思维导图:
文章地址:https://thenewstack.io/css-in-js-and-react-server-components-a-developer-guide/
文章来源:thenewstack.io
作者:Paul Scanlon
发布时间:2024/6/27 12:44
语言:英文
总字数:1042字
预计阅读时间:5分钟
评分:81分
标签:教程,CSS-in-JS,React 服务器组件,Linaria
以下为原文内容
本内容来源于用户推荐转载,旨在分享知识与观点,如有侵权请联系删除 联系邮箱 media@ilingban.com
With React’s evolving ecosystem, particularly with Next.js shifting toward a “server-first” approach, applications using CSS-in-JS solutions like Emotion and styled-components are facing significant challenges. These CSS-in-JS libraries are inherently incompatible with the new React paradigm.
While one could argue these libraries could be updated to align with the new server-first direction, it’s important to remember that they’re maintained by unpaid open source contributors. Expecting them to completely overhaul their libraries to accommodate changes in React is a daunting and potentially unrealistic task.
Let’s look at why some CSS-in-JS solutions are unable to work in the new server-first world, then I’ll introduce you to one alternative, Linaria, which uses an almost identical API as styled-components.
The RSC Paradigm
This is going to turn into a long-winded explanation, but it’s important to understand how React used to work (pre-React Server Components) and how it works now (post-RSC).
Pre-RSC: Both Server and Client
So let’s start at the beginning. Pre-RSC, React rendered a “component” on both the server and the client. React has always rendered the static parts of the HTML page on the server and sent that to the client to be “hydrated.” The hydration phase is client-side JavaScript that’s responsible for dealing with refs or attaching event handlers, which typically allow for interactivity.
If it feels a bit dumb to do this work twice — once on the server, then replay it again on the client — that’s because it kinda is. I’ve discussed this before by comparing React’s hydration with Qwik’s resumable approach, which for me makes much more sense.
Post-RSC: Server Only
However, in a post-RSC world, all React components by default are server-only. React renders the static parts of the HTML page, but doesn’t hydrate them on the client. This reduces/eliminates any client-side JavaScript. This is an interesting approach because in a post-RSC world, we’re able to make server-side requests from any component, at any level in the tree, not just at the route level, which is how Next.js previously worked.
React’s New Use Client Directive
In a post-RSC world you can still enable client-side JavaScript and React specific methods such as useState
, useEffect
, etc., but you have to be explicit and add the use client
directive to the top of the file so React will behave in the same way it always has.
Why Doesn’t CSS-in-JS Work With RSC?
To add a little more context, it’s important to understand how, for want of a better word, legacy CSS-in-JS libraries work before you can understand why they don’t work in a post-RSC world.
Libraries like Emotion and styled-components do a lot of the heavy lifting at runtime, on the client using client-side JavaScript, which we’ve established no longer exists in RSCs, or “server-only” components.
You’ve probably seen this in effect. If you inspect any app or site that uses e.g. styled-components, you’ll have noticed the weird-looking class names.
This is because with styled-components, you, the developer, don’t write CSS classes, you write components — and styled-components (the library) deals with extracting the styles, converting them to CSS that the browser can understand and generating a random but unique class name, then applying it to a DOM element to link the two together.
For example, here’s how you might define a HTML anchor element using styled-components for use in a React component.
When styled-components runs, it’ll create the class name (as seen above), add it to the DOM element, and convert the CSS values as defined when the styled.a
was created into CSS the browser can understand, such as.:
But as mentioned, this all happens at runtime, on the client, using client-side JavaScript.
Sadly then, because RSCs are designed to be rendered on the server and then sent as HTML to the client, they have specific characteristics and limitations — particularly regarding client-side JavaScript that prevents libraries like styled-components from working.
All Is Not Lost
There are a number of newer solutions to this problem that shift the heavy lifting from the client to the build. We already do a lot of heavy lifting here, converting TypeScript to “browser Js,” so doing CSS-in-JS stuff at this point seems like a great solution for the post-RSC world.
However, you may wonder: Won’t that mean developers the world over would need to rewrite all their styled.
declarations using some new fancy API? Because that would be a nightmare!
Thankfully, the creators of Linaria, which has actually been around since 2017, have opted to use a very similar API to that of styled-components. Pigment CSS from the MUI team has followed a similar pattern too, which is great news.
How Do RSC Compatible CSS-in-JS Libraries Work?
In the case of Linaria, it leverages CSS modules. If I use the styled.a
example again:
Instead of this turning into a random but unique class name, Linaria creates a [component name].module.css
file and converts the styled declaration into a real CSS named class, for instance:
During the build step of your application, an import to the CSS modules .css
file will be added to the component, and the styled declaration is converted into the underlying HTML element (in this case it’s an anchor element), and a reference to the class is added:
Since this all happens during the build step, there’s nothing for the browser to do — and thus, no client-side JavaScript required. It’s actually a pretty cool solution to the problem and all that’s required to migrate would be to uninstall styled-components, install Linaria, and perform a find and replace from import styled from 'styled-components';
to import styled from '@linaria/react';
.
Final Thoughts
So there you have it, when something as widely used as React completely changes the way it fundamentally works, many open source projects designed for it will need to change too — or, in some unfortunate cases, be retired to the history books. In JavaScript-land everything changes frequently, and all we can do is try to keep up!
That said, the dedication by the community to react (pun intended) and evolve when changes occur is incredible, and I’m glad I’m part of this crazy community. There’s never a dull moment!
YOUTUBE.COM/THENEWSTACK
Tech moves fast, don’t miss an episode. Subscribe to our YouTubechannel to stream all our podcasts, interviews, demos, and more.