如何在React App Server上渲染CSS

news/2024/7/7 12:55:46

Server-side rendering can be challenging due to ambiguity. Open-source tools like Next.js (React) and Nuxt.js(Vue) help streamline the process of rendering your app views to a server.

由于含糊不清,服务器端渲染可能具有挑战性。 诸如Next.js (React)和Nuxt.js (Vue)之类的开源工具可帮助简化将应用程序视图呈现到服务器的过程。

In this article, we will go over the challenges of rendering CSS on the server and then demonstrate how we can overcome these challenges. If you would like additional guidance on Next.js, you can get started with this short article.

在本文中,我们将介绍在服务器上呈现CSS的挑战,然后演示如何克服这些挑战。 如果您想获得有关Next.js的其他指导,可以开始阅读这篇简短的文章 。

React中的样式模式 (Style Patterns in React)

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应用:

整体风格 (Global Styles)

This is the pattern we are used to practicing. It’s common in the web ecosystem generally, not just React. Basically, you have a local or CDN stylesheet included in your HTML page using the link tag:

这是我们习惯的模式。 通常在Web生态系统中很常见,而不仅仅是React。 基本上,您使用link标记在HTML页面中包含本地或CDN样式表:

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/7.0.0/normalize.css" />

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重置/默认包含,则需要全局包含样式。

内联样式 (Inline Styles)

These styles are applied to DOM elements or React components using the React 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'
}

<h1 style={titleStyle} {...props}>{props.children}<h1>

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逻辑。

组件样式 (Component Styles)

Component styles encourage reuse and help you to compose styles and components better. You need a utility or library to help you accomplish this. Style loaders, styled-components, Glamor, etc are

组件样式鼓励重用,并帮助您更好地组合样式和组件。 您需要一个实用程序或库来帮助您完成此任务。 样式加载器, 样式组件 , Glamour等是

样式化的组件 (Styled Components)

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,起初听起来可能有些笨拙,但想到了它-这是一个了不起的概念。 当我可以在JavaScript中为给定CSS块进行计算,创建变量并遍历数据时,谁需要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)。

设置一个Next.js项目 (Setup a Next.js Project)

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 = () => <h1>Hi, new Next.js project</h1>;
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.

让我们添加一些样式。

具有样式化组件的样式 (Styles with Styled Components)

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 = () =>
  <div>
    <Head>
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/7.0.0/normalize.css" />
      <link href="https://fonts.googleapis.com/css?family=Raleway" rel="stylesheet">
    </Head>
    <h1>Hi, new Next.js project</h1>
  </div>;

export default Index;

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:

在“索引”页面中导入基本样式:

<Head>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/7.0.0/normalize.css" />
  <link href="https://fonts.googleapis.com/css?family=Raleway" rel="stylesheet" />
  <link rel="stylesheet" href="/static/base.css" />
</Head>

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) => <button {...props}>{props.children}</button>
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的Button styled-componentsButtonBase返回按钮的骨架,而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 = () => <div>
  <Head>
    ...
  </Head>
  <h1>Hi, new Next.js project</h1>
  <Button>Clicker</Button>
</div>;
export default Index;

This gives us a fine looking button after hot-reloading the page. How hard-reload the page and see what happens:

热重新加载页面后,这为我们提供了一个漂亮的按钮。 如何硬刷新页面并查看会发生什么:

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.

您会看到一个错误,显示在类名中未匹配。 这是因为,当您重新加载内容时,首先会从服务器获取内容。 不幸的是,样式化组件没有呈现给服务器,这使得它们当时不可用。 让我们看一个解决方案。

样式的JSX (Styled JSX)

The team working on Next.js introduced a library called styled jsx 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的团队引入了一个称为样式jsx的库,以帮助控制减轻该问题。 该库可确保您编写的样式在服务器以及浏览器上呈现,而不仅仅是在浏览器上呈现。

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 => (
  <button {...props}>
    {props.children}
    <style jsx>{`
      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;
    `}</style>
  </button>
);
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中使用选择器:

(
<div {...props}>
<h1 className="title">Hi Title</h1>
<button>Clicker</button>
    <style jsx>{`
      h1.title {
        color: #222
      }
      button {
        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;
      }
    `}</style>
</div>
)

And that’s how you render styles to a server in Next.js projects.

这就是在Next.js项目中将样式渲染到服务器的方式。

结论 (Conclusion)

You can learn more about styled jsx on the project’s repository.

您可以在项目的存储库中了解有关样式化jsx的更多信息。

翻译自: https://www.digitalocean.com/community/tutorials/rendering-css-on-servers-for-nextjs-react-apps


http://www.niftyadmin.cn/n/3648996.html

相关文章

Android存储方式二:sqlite数据库

说明 应用运行需要保存一系列有一定结构的数据, 比如说公司员工信息 文件类型: .db 数据保存的路径: /data/data/projectPackage/databases/xxx.db 默认情况下其它应用不能访问, 当前应用可以通过ContentProvider提供其它应用操作 应用卸载时会删除此数据 sqlite数据库 …

事件机制分发

相关API 1. MotionEvent : 触屏事件 int ACTION_DOWN0 : 代表down int ACTION_MOVE2 ; 代表move int ACTION_UP1 : 代表up getAction() : 得到事件类型值 getX() : 得到事件发生的x轴坐标(相对于当前视图) getRawX() :得到事件发生的x轴坐标(相对于屏幕左顶点) getY() …

Android TabActivity的生命周期

在TabActivity中&#xff0c;只在第一次进入时走了onCreate()、onStart()、onResume()三个阶段&#xff0c;然后在退出该页面时走了onPause()、onStop()和onDestroy()两个阶段。其他时间无论其中的子Activity如何切换&#xff0c;都不会再进入TabActivity的生命周期。 而子Acti…

three.js使用svg_如何使用SVG和anime.js构建弹性范围输入

three.js使用svg介绍 (Introduction) In HTML5, many new types of input attributes were introduced for the form element, such as color, date, range, and many more. Although functionally these new types of input works, they often do not meet the aesthetic need…

我们正处在IT殖民时代,需要突破的勇气,或者就这样继续下去...

IT殖民地&#xff0c;似乎有点危言耸听。但是从客观的事实来看&#xff0c;这个称呼并不离奇&#xff0c;尤其在企业级市场上&#xff08;IT消费品市场还好些&#xff09;。我们的操作系统都是Windows、AIX、HP-UX、Solaris&#xff0c;Redhat Linux&#xff0c;SuSE Linux&…

Android 使用Fragment 替换 TabActivity

可以分为下面的几部分&#xff1a; 使用支持库 创建一个Fragment 创建一个动态UI 多个Fragment之间的通信 1、使用支持库 如果您的应用需要运行在3.0及以上的版本&#xff0c;可以忽略这部分内容。 如果您的应用使用在3.0以下、1.6及以上的版本&#xff0c;需要使用支持库来…

如何在Visual Studio Code中使用Live Share

介绍 (Introduction) Live Share is an extension for VS Code that enables real-time collaboration between developers. It gives users the ability to share a session with someone else, allowing them to edit code as well as share a sever and debugging session. …

四大组件之service简单介绍和AIDL的简单使用

Service是什么 1.Service是一个应用组件, 它用来在后台完成一个时间跨度比较大的工作且没有关联任何界面 2.一个Service可以完成下面这些工作:访问网络 播放音乐 文件IO操作 大数据量的数据库操作 …… 3. 服务的特点: Service在后台运行&#xff0c;不用与用户进行交互 …