本文共 10022 字,大约阅读时间需要 33 分钟。
react 应用动态css
Server-side rendering is not such an easy task. Its ambiguity is independent of the library — it’s just generally daunting. This is why some amazing developers are out there building open source tools like (React) and (Vue) to help simplify the process of rendering your app views to a server. I have written previously on Next.js so you can get started with if you haven’t used Next.js before.
服务器端渲染并不是一件容易的事。 它的歧义性与库无关,只是一般而言令人生畏。 这就是为什么一些出色的开发人员在那里构建诸如 (React)和 (Vue)之类的开源工具来帮助简化将应用程序视图呈现到服务器的过程。 我之前已经在Next.js上进行过编写,因此如果您以前没有使用过Next.js,则可以开始阅读 。
While working with Next.js, I ran into an obscure problem. This had to do with how styles are rendered on the server, and it never struck till now that styles are also first class citizens for server-side rendering.
在使用Next.js时,我遇到了一个晦涩的问题。 这与样式在服务器上的呈现方式有关,直到现在,样式还是服务器端呈现的头等公民,这才引起人们的关注。
In this article, I will describe these challenges of rendering CSS on the server and then show you how we can overcome the challenges.
在本文中,我将描述在服务器上呈现CSS所面临的挑战,然后向您展示我们如何克服这些挑战。
There are few common ways to write CSS in React which all work. Some of these patters are widely used, some are frowned upon, while some are fairly used. Depending on your situation, you are applying styles to your React app in one of the following ways:
在React中编写CSS的几种通用方法几乎都能正常工作。 这些模式中有一些被广泛使用,有些被皱眉,而有些则被合理使用。 根据您的情况,您可以通过以下方式之一将样式应用于React应用:
link
tag: 整体风格 :这是我们习惯的模式。 通常在Web生态系统中很常见,而不仅仅是React。 基本上,您使用link
标记将本地或CDN样式表包含在HTML页面中: This is the less preferred styling pattern because it does not encourage component reuse, neither does it encourage style composition. That global styles are discouraged doesn’t imply they are completely useless. There are cases like font inclusion and CSS resets/defaults inclusion where you would need to include styles globally.
这是不太受欢迎的样式模式,因为它不鼓励组件重用,也不鼓励样式组合。 不鼓励使用全局样式并不意味着它们完全没有用。 在某些情况下,如字体包含和CSS重置/默认包含,则需要全局包含样式。
style
property. The implementation much like the HTML inline style attribute but uses the JavaScript element.style
API. Here is an example: 内联样式 :这些样式使用React style
属性应用于DOM元素或React组件。 该实现非常类似于HTML内联样式属性,但使用JavaScript element.style
API。 这是一个例子: const titleStyle = { fontSize: '4rem'; lineHeight: '1.6'; color: '#222'}{ props.children}
This pattern encourages style and component composition as well as reuse. But it’s a bit hard to write style like this. Think of handling hover or focus state with pseudo selectors. You will have managed a lot of JavaScript logic across your project just to do that.
这种模式鼓励样式和组件组成以及重用。 但是,要编写这样的样式有点困难。 考虑使用伪选择器处理悬停或焦点状态。 为此,您将在整个项目中管理很多JavaScript逻辑。
In the three patterns I mentioned, styled-components are most favored. They are inline component styles but with more power to do things like complex (pseudo) selection, nesting, etc. They are referred to as CSS in JS which at first might sound awkward, but come to think of it — it’s an amazing concept. Who needs Sass when I can do my calculations, create variables and iterate over data right in JavaScript for a given block of CSS?
在我提到的三种模式中,样式组件是最受青睐的。 它们是内联组件样式,但是具有执行复杂(伪)选择,嵌套等功能的能力。它们在JS中被称为CSS,起初听起来可能有些笨拙,但是想到了它-这是一个了不起的概念。 当我可以针对给定CSS块在JavaScript中进行计算,创建变量并遍历数据时,谁需要Sass?
To see how to use styled components (or component styles), let’s create a new Next.js (which is React based).
要查看如何使用样式化的组件(或组件样式),让我们创建一个新的Next.js(基于React)。
Create a project by creating an empty folder on your machine, then run the following command on that folder:
通过在计算机上创建一个空文件夹来创建项目,然后在该文件夹上运行以下命令:
yarn init -y
(Make sure you have Yarn installed)
(确保已安装纱)
This will create a package.json
file with the following content:
这将创建一个具有以下内容的package.json
文件:
{ "name": "css-ssr-next", "version": "1.0.0", "main": "index.js", "license": "MIT"}
Install Next.js, React, and React DOM:
安装Next.js,React和React DOM:
yarn add next react react-dom
Then update the package.json
to start a Next.js app with dev
script:
然后更新package.json
以使用dev
脚本启动Next.js应用程序:
{ "name": "css-ssr-next", "version": "1.0.0", "main": "index.js", "license": "MIT", "scripts": { "dev": "next" }, "dependencies": { "next": "^4.2.1", "react": "^16.2.0", "react-dom": "^16.2.0" }}
Create a pages folder and add an index.js
with the following content:
创建一个页面文件夹,并添加具有以下内容的index.js
:
import React from 'react';const Index = () =>Hi, new Next.js project
;export default Index;
Now run the script to start the dev server:
现在运行脚本以启动开发服务器:
yarn dev
You should get this in your browser at localhost’s port 3000
:
您应该在浏览器的本地主机端口3000
获得此命令:
Let’s add some styles.
让我们添加一些样式。
Let’s use the styled-components
library to see how we can style components. First, use the Head
component from Next to normalize styles using normalize.css
:
让我们使用styled-components
库来查看如何styled-components
设置样式。 首先,使用Next中的Head
组件使用normalize.css
来规范样式:
import React from 'react';import Head from 'next/head';const Index = () =>;export default Index;Hi, new Next.js project
I also added a font from Google font. This wouldn’t change anything until the style is applied to the body element. Create a static
folder on the root of your Next.js project and add a base.css
file with the following CSS content:
我还从Google字体添加了一种字体。 在将样式应用于body元素之前,此操作不会更改任何内容。 创建一个static
您Next.js项目的根文件夹,并添加base.css
文件,下面CSS内容:
body { font-family: 'Raleway', sans-serif; color: #222;}
Import the base style in the Index page:
在“索引”页面中导入基本样式:
You can see that the font changed and in the browser:
您可以在浏览器中看到字体已更改:
We are done with the dirty global style job. Let's start adding components with composed styles. Install styled-components
:
我们完成了肮脏的全球风格工作。 让我们开始添加具有组合样式的组件。 安装styled-components
:
yarn add styled-components
Next, create a components
folder and add a Button.js
file. Update the file with the following:
接下来,创建一个components
文件夹并添加一个Button.js
文件。 使用以下更新文件:
import React from 'react';import styled from 'styled-components';const ButtonBase = (props) => const Button = styled(ButtonBase)` /* Rectangle 2: */ background: #0077E2; box-shadow: 0 2px 7px 0 rgba(120,137,149,0.25); border-radius: 3px; text-transform: uppercase; padding: 10px; color: #fff; border: #0077E2;`export default Button;
We are using styled-components
imported as styled
to style a Button. ButtonBase
returns a skeleton of the button while Button
returns a component with a styled ButtonBase
.
我们使用导入为styled
按钮styled-components
。 ButtonBase
返回按钮的骨架,而Button
返回具有样式化ButtonBase
的组件。
Import and use the button in the Index page:
导入并使用“索引”页面中的按钮:
import React from 'react';import Head from 'next/head';import Button from '../components/Button'const Index = () =>...;export default Index;Hi, new Next.js project
This gives us a fine looking button after hot-reloading the page. How hard-reload the page and see what happens:
热重新加载页面后,这为我们提供了一个漂亮的按钮。 如何硬刷新页面并查看会发生什么:
Weird, right? The button styles seem to be missing, but somehow, the base styles are intact. Now view the page source to dig what happened:
奇怪吧? 按钮样式似乎丢失了,但是不知何故,基本样式是完整的。 现在查看页面源代码以了解发生了什么:
The blue box shows that the content is rendered to the server, but it doesn’t show any style anywhere on the page relating to the button. On the other hand, the font styles were applied. From what you can see in the red box, the external files were rendered to the server successfully.
蓝色框显示内容已呈现到服务器,但在页面上与按钮相关的任何位置均未显示任何样式。 另一方面,应用了字体样式。 从红色框中可以看到,外部文件已成功呈现到服务器。
So what went wrong with the component styles? Take a look at the console:
那么组件样式出了什么问题? 看一下控制台:
You can see an error showing a miss-match in the class name. This is because, when you reload, content is first fetched from the server. Unfortunately, styled-components are not rendered to the server which makes them unavailable at that time. Let’s take a look at a solution.
您会看到一个错误,显示类名中的未匹配项。 这是因为,当您重新加载内容时,首先会从服务器获取内容。 不幸的是,样式化组件没有呈现给服务器,这使得它们当时不可用。 让我们看一个解决方案。
The team working on Next.js introduced a library called to help control mitigate this problem. The library ensures that styles you write are rendered on the server as well as the browser and not just the browser alone.
研究Next.js的团队引入了一个称为的库,以帮助控制该问题。 该库可确保您编写的样式在服务器以及浏览器上呈现,而不仅仅是在浏览器上呈现。
It already comes bundled with Next.js, so you don’t need to install. Just update the Button
component to make use of it:
它已经与Next.js捆绑在一起,因此您不需要安装。 只需更新Button
组件即可使用它:
import React from 'react';const Button = props => ( );export default Button;
Before the closing tag of the root element in a component we want to style, you can create a style element with the jsx
attribute. In the style element, open a curly brace that contains template strings. The strings should be valid CSS styles and server as your component style. No matter how hard you reload this time, your style stays put:
在我们要设置样式的组件中的根元素的结束标记之前,您可以使用jsx
属性创建一个样式元素。 在样式元素中,打开一个包含模板字符串的花括号。 字符串应为有效CSS样式,并且服务器应为组件样式。 无论您这次重新加载有多困难,样式都会保持不变:
The blue box in the image above shows that the button style is now rendered to the server as well.
上图中的蓝色框显示按钮样式现在也已呈现给服务器。
You can also use selectors in styled jsx if your component is not composed of only one element:
如果您的组件并非仅由一个元素组成,则还可以在样式jsx中使用选择器:
()Hi Title
And that’s how you render styles to a server in Next.js projects. You can learn more about styled jsx on the project’s repository.
这就是在Next.js项目中将样式渲染到服务器的方式。 您可以在项目的存储库中了解有关样式化jsx的更多信息。
翻译自:
react 应用动态css
转载地址:http://wguwd.baihongyu.com/