Thứ năm, 12/12/2019 | 00:00 GMT+7

Cách hiển thị CSS trên server ứng dụng React


Kết xuất phía server có thể gặp khó khăn do không rõ ràng. Các công cụ open-souce như Next.js (React) và Nuxt.js (Vue) giúp hợp lý hóa quá trình hiển thị các chế độ xem ứng dụng của bạn tới một server .

Trong bài viết này, ta sẽ xem xét các thách thức khi hiển thị CSS trên server và sau đó trình bày cách ta có thể vượt qua những thách thức này. Nếu bạn muốn có thêm hướng dẫn về Next.js, bạn có thể bắt đầu với bài viết ngắn này .

Các mẫu kiểu trong React

Có một số cách phổ biến để viết CSS trong React mà tất cả đều hoạt động. Một số bằng sáng chế này được sử dụng rộng rãi, một số bị phản đối, trong khi một số được sử dụng khá phổ biến. Tùy thuộc vào tình huống của bạn, bạn đang áp dụng các kiểu cho ứng dụng React của bạn theo một trong những cách sau:

Phong cách global

Đây là khuôn mẫu mà ta quen thực hành. Nó phổ biến trong hệ sinh thái web nói chung, không chỉ React. Về cơ bản, bạn có một biểu định kiểu local hoặc CDN có trong trang HTML của bạn bằng cách sử dụng thẻ link :

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

Đây là kiểu tạo kiểu ít được ưa thích hơn vì nó không khuyến khích sử dụng lại thành phần, cũng không khuyến khích việc tạo kiểu. Các phong cách global không được khuyến khích không nghĩa là chúng hoàn toàn vô dụng. Có những trường hợp như bao gồm phông chữ và bao gồm đặt lại / mặc định CSS trong đó bạn cần bao gồm các kiểu trên phạm vi global .

Kiểu nội tuyến

Các kiểu này được áp dụng cho các phần tử DOM hoặc các thành phần React bằng cách sử dụng thuộc tính style React. Việc triển khai giống như thuộc tính kiểu nội tuyến HTML nhưng sử dụng API element.style JavaScript. Đây là một ví dụ:

const titleStyle = {
  fontSize: '4rem';
  lineHeight: '1.6';
  color: '#222'
}

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

Mô hình này khuyến khích phong cách và bố cục thành phần cũng như tái sử dụng. Nhưng hơi khó để viết kiểu như thế này. Hãy nghĩ đến việc xử lý trạng thái di chuột hoặc lấy nét bằng các bộ chọn giả. Bạn sẽ quản lý rất nhiều logic JavaScript trong dự án của bạn chỉ để làm điều đó.

Kiểu thành phần

Các kiểu thành phần khuyến khích sử dụng lại và giúp bạn soạn các kiểu và thành phần tốt hơn. Bạn cần một tiện ích hoặc thư viện để giúp bạn thực hiện điều này. Bộ nạp kiểu, thành phần kiểu , Glamour , v.v. là

Các thành phần được tạo kiểu

Trong ba mẫu tôi đã đề cập, các thành phần được tạo kiểu được ưa chuộng nhất. Chúng là các kiểu thành phần nội tuyến nhưng có nhiều quyền hơn để thực hiện những việc như lựa chọn phức tạp (giả), lồng nhau, v.v. Chúng được gọi là CSS trong JS thoạt nghe có vẻ khó hiểu, nhưng hãy nghĩ lại - đó là một khái niệm tuyệt vời. Ai cần Sass khi tôi có thể thực hiện các phép tính, tạo biến và lặp lại dữ liệu ngay trong JavaScript cho một khối CSS nhất định?

Để xem cách sử dụng các thành phần được tạo kiểu (hoặc các kiểu thành phần), hãy tạo một Next.js mới (dựa trên React).

Cài đặt một Dự án Next.js

Tạo một dự án bằng cách tạo một folder trống trên máy của bạn, sau đó chạy lệnh sau trên folder đó:

yarn init -y

(Đảm bảo rằng bạn đã cài đặt Yarn)

Thao tác này sẽ tạo một file package.json với nội dung sau:

{
  "name": "css-ssr-next",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT"
}

Cài đặt Next.js, React và React DOM:

yarn add next react react-dom

Sau đó, cập nhật package.json để khởi động ứng dụng Next.js với tập lệnh dev :

{
  "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"
  }
}

Tạo một folder trang và thêm một index.js với nội dung sau:

import React from 'react';
const Index = () => <h1>Hi, new Next.js project</h1>;
export default Index;

Bây giờ hãy chạy tập lệnh để khởi động server nhà phát triển:

yarn dev

Bạn sẽ nhận được điều này trong trình duyệt của bạn tại cổng 3000 của localhost:

thiếu hình ảnh

Hãy thêm một số phong cách.

Phong cách với các thành phần được tạo kiểu

Hãy sử dụng thư viện styled-components để xem cách ta có thể tạo kiểu cho các thành phần. Đầu tiên, sử dụng thành phần Head từ Next để chuẩn hóa các kiểu bằng cách sử dụng 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;

Tôi cũng đã thêm một phông chữ từ phông chữ Google. Điều này sẽ không thay đổi bất cứ điều gì cho đến khi kiểu được áp dụng cho phần tử body. Tạo một folder static trên folder root của dự án Next.js của bạn và thêm file base.css với nội dung CSS sau:

body {
  font-family: 'Raleway', sans-serif;
  color: #222;
}

Nhập kiểu cơ sở trong trang Chỉ mục:

<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>

Bạn có thể thấy rằng phông chữ đã thay đổi và trong trình duyệt:

thiếu hình ảnh

Ta đã hoàn thành công việc theo phong cách global bẩn thỉu. Hãy bắt đầu thêm các thành phần với các kiểu sáng tác. Cài đặt styled-components :

yarn add styled-components

Tiếp theo, tạo một folder components và thêm file Button.js . Cập nhật file với nội dung sau:

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;

Ta đang sử dụng styled-components được nhập styled nhập styled để styled cho Nút. ButtonBase trả về một khung của nút trong khi Button trả về một thành phần có ButtonBase được tạo kiểu.

Nhập và sử dụng nút trong trang Chỉ mục:

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;

thiếu hình ảnh

Điều này cung cấp cho ta một nút trông đẹp sau khi reload nóng trang. Reload trang và xem điều gì sẽ xảy ra:

thiếu hình ảnh

Các kiểu nút dường như bị thiếu, nhưng bằng cách nào đó, các kiểu cơ bản vẫn còn nguyên vẹn. Bây giờ hãy xem nguồn trang để tìm hiểu những gì đã xảy ra:

thiếu hình ảnh

Hộp màu xanh lam cho thấy rằng nội dung được hiển thị cho server , nhưng nó không hiển thị bất kỳ kiểu nào ở bất kỳ đâu trên trang liên quan đến nút. Mặt khác, các kiểu phông chữ đã được áp dụng. Từ những gì bạn có thể thấy trong hộp màu đỏ, các file bên ngoài đã được hiển thị thành công cho server .

Vậy điều gì đã xảy ra với các kiểu thành phần? Hãy xem console :

thiếu hình ảnh

Bạn có thể thấy lỗi hiển thị sai khớp trong tên lớp. Điều này là do, khi bạn reload , nội dung sẽ được tải đầu tiên từ server . Thật không may, các thành phần được tạo kiểu không được hiển thị cho server khiến chúng không khả dụng vào thời điểm đó. Ta hãy xem xét một giải pháp.

JSX được tạo kiểu

Group làm việc trên Next.js đã giới thiệu một thư viện có tên jsx được tạo kiểu để giúp kiểm soát giảm thiểu vấn đề này. Thư viện đảm bảo các kiểu bạn viết được hiển thị trên server cũng như trình duyệt chứ không chỉ trình duyệt một mình.

Nó đã đi kèm với Next.js, vì vậy bạn không cần phải cài đặt. Chỉ cần cập nhật thành phần Button để sử dụng nó:

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;

Trước thẻ đóng của phần tử root trong thành phần mà ta muốn tạo kiểu, bạn có thể tạo phần tử kiểu với thuộc tính jsx . Trong phần tử kiểu, hãy mở một dấu ngoặc nhọn chứa các chuỗi mẫu. Các chuỗi phải là kiểu CSS hợp lệ và server làm kiểu thành phần của bạn. Dù bạn reload lần này khó đến mức nào, phong cách của bạn vẫn giữ nguyên:

thiếu hình ảnh

Hộp màu xanh lam trong hình trên cho thấy kiểu nút giờ đây cũng được hiển thị cho server .

Bạn cũng có thể sử dụng bộ chọn trong jsx theo kiểu nếu thành phần của bạn không chỉ bao gồm một phần tử:

(
<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>
)

Và đó là cách bạn hiển thị các kiểu cho một server trong các dự án Next.js.

Kết luận

Bạn có thể tìm hiểu thêm về jsx được tạo kiểu trên kho của dự án.


Tags:

Các tin liên quan

Cách tạo Thư viện ảnh cuộn vô hạn với React và CSS Grid
2019-12-12
Cách tạo node tải xuống với các tương tác nhỏ với CSS, anime.js và segment.js
2019-12-12
Cách giải quyết tắc nghẽn CSS quy mô lớn với ITCSS và BEM
2019-12-12
Đặt, giãn cách và mật độ trong CSS Grid
2019-12-12
Hiểu tính cụ thể trong CSS
2019-09-03
CSS sẽ thay đổi Thuộc tính: Khi nào và Không sử dụng Nó
2019-08-26
Trình xử lý nhấp chuột chỉ dành cho CSS sử dụng: target Pseudo-Class (Không có JavaScript)
2019-08-22
Giới thiệu về Tailwind CSS
2019-08-13
Hiểu CSS Float
2019-06-07
Giới thiệu về Bulma CSS với React
2018-10-12