Thứ ba, 09/06/2020 | 00:00 GMT+7

Cách tạo kiểu cho các thành phần React

Trong hướng dẫn này, bạn sẽ tìm hiểu ba cách khác nhau để tạo kiểu cho các thành phần React : Trang tính kiểu xếp tầng đơn giản (CSS) , kiểu nội tuyến với các đối tượng kiểu JavaScriptJSS , một thư viện để tạo CSS bằng JavaScript . Mỗi tùy chọn này đều có ưu điểm và nhược điểm, một số giúp bạn bảo vệ tốt hơn trước các xung đột kiểu hoặc cho phép bạn tham khảo trực tiếp các đạo cụ hoặc dữ liệu động khác. Nhưng tất cả các tùy chọn đều có một điểm chung: Chúng cho phép bạn giữ các kiểu dành riêng cho thành phần của bạn gần với thành phần, giúp các thành phần dễ dàng sử dụng lại trong một dự án hoặc thậm chí trên nhiều dự án không liên quan.

Mỗi tùy chọn này đều dựa trên các thuộc tính CSS. Để sử dụng CSS thuần túy mà không có bất kỳ dữ liệu thời gian chạy nào, bạn có thể nhập các biểu định kiểu. Nếu bạn muốn tạo kiểu được tích hợp với thành phần, bạn có thể sử dụng các đối tượng kiểu nội tuyến sử dụng tên thuộc tính CSS làm khóa và kiểu làm giá trị. Cuối cùng, nếu bạn muốn kết hợp, bạn có thể sử dụng thư viện của bên thứ ba như JSS để viết CSS của bạn theo cú pháp JavaScript, một khái niệm phần mềm được gọi là CSS-in-JS .

Để minh họa các phương pháp này, bạn sẽ xây dựng một thành phần alert ví dụ sẽ hiển thị kiểu thành công hoặc kiểu lỗi tùy thuộc vào phần mềm hỗ trợ . Thành phần alert sẽ lấy bất kỳ số lượng trẻ em nào. Điều này nghĩa là bạn cần phải thận trọng với các xung đột về kiểu dáng, vì bạn không có cách nào biết được kiểu dáng mà các thành phần con sẽ có. Sau khi tạo thành phần alert , bạn sẽ cấu trúc lại nó bằng cách sử dụng từng tùy chọn tạo kiểu để bạn có thể thấy điểm giống và khác nhau giữa các phương pháp.

Yêu cầu

Bước 1 - Tạo một dự án trống

Trong bước này, bạn sẽ tạo một dự án mới bằng Tạo ứng dụng React . Sau đó, bạn sẽ xóa dự án mẫu và các file liên quan được cài đặt khi bạn khởi động dự án. Cuối cùng, bạn sẽ tạo một cấu trúc file đơn giản để tổ chức các thành phần của bạn .Điều này sẽ cung cấp cho bạn cơ sở vững chắc để xây dựng ứng dụng mẫu của hướng dẫn này để tạo kiểu trong bước tiếp theo.

Để bắt đầu, hãy tạo một dự án mới. Trong terminal của bạn, hãy chạy tập lệnh sau để cài đặt một dự án mới bằng cách sử dụng create-react-app :

  • npx create-react-app styling-tutorial

Sau khi dự án kết thúc, hãy thay đổi vào folder :

  • cd styling-tutorial

Trong cửa sổ hoặc tab terminal mới, hãy bắt đầu dự án bằng cách sử dụng tập lệnh bắt đầu Tạo ứng dụng React . Trình duyệt sẽ tự động làm mới các thay đổi, vì vậy hãy để tập lệnh này chạy trong khi bạn làm việc:

  • npm start

Bạn sẽ nhận được một server local đang chạy. Nếu dự án không mở trong cửa sổ trình duyệt, bạn có thể mở bằng http://localhost:3000/ . Nếu bạn đang chạy điều này từ một server từ xa, địa chỉ sẽ là http:// your_domain :3000 .

Trình duyệt của bạn sẽ tải với một ứng dụng React đơn giản được bao gồm như một phần của Create React App:

Dự án mẫu phản ứng

Bạn sẽ xây dựng một tập hợp các thành phần tùy chỉnh hoàn toàn mới, vì vậy bạn cần bắt đầu bằng cách xóa một số mã soạn sẵn để bạn có thể có một dự án trống.

Để bắt đầu, hãy mở src/App.js trong editor . Đây là thành phần root được đưa vào trang. Tất cả các thành phần sẽ bắt đầu từ đây. Bạn có thể tìm thêm thông tin về App.js tại Cách cài đặt một dự án React với Tạo ứng dụng React .

Mở src/App.js bằng lệnh sau:

  • nano src/App.js

Bạn sẽ thấy một file như thế này:

style-tutorial / src / App.js
import React from 'react'; import logo from './logo.svg'; import './App.css';  function App() {   return (     <div className="App">       <header className="App-header">         <img src={logo} className="App-logo" alt="logo" />         <p>           Edit <code>src/App.js</code> and save to reload.         </p>         <a           className="App-link"           href="https://reactjs.org"           target="_blank"           rel="noopener noreferrer"         >           Learn React         </a>       </header>     </div>   ); }  export default App; 

Xóa import logo from './logo.svg'; dòng import logo from './logo.svg'; . Sau đó, thay thế mọi thứ trong câu lệnh return để trả về một tập hợp các thẻ trống: <></> . Điều này sẽ cung cấp cho bạn một trang hợp lệ mà không trả lại gì. Mã cuối cùng sẽ giống như sau:

style-tutorial / src / App.js
 import React from 'react'; import './App.css';  function App() {   return <></>; }  export default App; 

Lưu và thoát khỏi editor .

Cuối cùng, xóa logo. Bạn sẽ không sử dụng nó trong ứng dụng của bạn và bạn nên xóa các file không sử dụng khi làm việc. Nó sẽ giúp bạn khỏi nhầm lẫn về lâu dài.

Trong cửa sổ terminal , nhập lệnh sau:

  • rm src/logo.svg

Nếu bạn nhìn vào trình duyệt của bạn , bạn sẽ thấy một màn hình trống.

màn hình trống trong chrome

Đến đây bạn đã hoàn thành dự án Tạo ứng dụng React mẫu, hãy tạo một cấu trúc file đơn giản. Điều này sẽ giúp bạn giữ cho các thành phần của bạn bị cô lập và độc lập.

Tạo một folder được gọi là components trong folder src . Điều này sẽ chứa tất cả các thành phần tùy chỉnh của bạn.

  • mkdir src/components

Mỗi thành phần sẽ có folder riêng để lưu trữ file thành phần cùng với các kiểu, hình ảnh và bài kiểm tra.

Tạo folder cho App :

  • mkdir src/components/App

Di chuyển tất cả các file App vào folder đó. Sử dụng ký tự đại diện, * , để chọn các file nào bắt đầu bằng App. dù phần mở rộng file . Sau đó, sử dụng lệnh mv để đưa chúng vào folder mới:

  • mv src/App.* src/components/App

Tiếp theo, cập nhật đường dẫn nhập tương đối trong index.js , là thành phần root khởi động toàn bộ quá trình:

  • nano src/index.js

Câu lệnh nhập cần trỏ đến file App.js trong folder App , vì vậy hãy thực hiện thay đổi được đánh dấu sau:

style-tutorial / src / index.js
import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './components/App/App'; import * as serviceWorker from './serviceWorker';  ReactDOM.render(   <React.StrictMode>     <App />   </React.StrictMode>,   document.getElementById('root') );  // If you want your app to work offline and load faster, you can change // unregister() to register() below. Note this comes with some pitfalls. // Learn more about service workers: https://bit.ly/CRA-PWA serviceWorker.unregister(); 

Lưu và thoát khỏi file .

Bây giờ dự án đã được cài đặt , bạn có thể tạo thành phần đầu tiên của bạn .

Bước 2 - Tạo kiểu cho một thành phần bằng CSS thuần túy

Trong bước này, bạn sẽ xây dựng thành phần Alert mẫu sẽ hiển thị cảnh báo trên trang web. Bạn sẽ tạo kiểu này bằng cách sử dụng CSS thuần túy, bạn sẽ nhập trực tiếp vào thành phần. Điều này sẽ đảm bảo các kiểu của thành phần vẫn được kết hợp chặt chẽ với JavaScript và JSX của thành phần. Bạn cũng cần tạo một thành phần sẽ triển khai thành phần Alert để xem cách các kiểu có thể ảnh hưởng đến trẻ em và cách bạn có thể sử dụng các đạo cụ để thay đổi kiểu động.

Đến cuối bước này, bạn sẽ tạo một số thành phần sử dụng CSS thuần túy được nhập trực tiếp vào thành phần.

Xây dựng thành phần cảnh báo

Để bắt đầu, hãy tạo một thành phần Alert mới. Đầu tiên, tạo folder :

  • mkdir src/components/Alert

Tiếp theo, mở Alert.js :

  • nano src/components/Alert/Alert.js

Thêm một thành phần cơ bản trả về chuỗi Alert :

style-tutorial / src / components / Alert / Alert.js
import React from 'react';  export default function Alert() {   return <div>Alert</div> } 

Lưu và đóng file .

Tiếp theo, mở App.js :

  • nano src/components/App/App.js

Nhập thành phần Alert và hiển thị nó bên trong <div> bằng cách thêm mã được đánh dấu:

style-tutorial / src / components / App / App.js
import React from 'react'; import './App.css';  import Alert from '../Alert/Alert';  function App() {   return (     <div className="wrapper">       <Alert />     </div>   ) }  export default App; 

Trong mã này, bạn đã cấp cho <div> một className của wrapper , sẽ được sử dụng để tạo kiểu sau này.

Lưu và đóng file . Khi bạn làm như vậy, trình duyệt sẽ làm mới và bạn sẽ thấy thành phần của bạn :

Trình duyệt có cảnh báo

Tiếp theo, bạn sẽ tạo kiểu cho thành phần App để cung cấp cho nó một số đệm để thành phần Alert không quá gần với cạnh. Mở file App.css :

  • nano src/components/App/App.css

Tệp này sử dụng CSS chuẩn. Để thêm phần đệm vào shell bọc, hãy thay thế mã mặc định bằng một luật như bạn làm đối với CSS trong một dự án HTML thuần túy. Trong trường hợp này, hãy thêm phần padding 20px :

style-tutorial / src / components / App / App.css
.wrapper {     padding: 20px; } 

Lưu và đóng file . Khi bạn làm như vậy, trang sẽ làm mới và bạn sẽ thấy phần đệm bổ sung:

Trình duyệt có thêm đệm

Khi bạn sử dụng Create React App, webpack sẽ lấy CSS đã nhập và thêm nó vào thẻ kiểu ở đầu file được hiển thị trong trình duyệt. Nếu bạn nhìn vào phần tử <head> trong nguồn trang của bạn , bạn sẽ thấy các kiểu:

Thẻ kiểu trong nguồn trang

Điều này nghĩa là bạn có thể giữ CSS bên cạnh thành phần và nó sẽ được thu thập cùng nhau trong giai đoạn xây dựng . Điều đó cũng nghĩa là phong cách của bạn có phạm vi global , có thể tạo ra xung đột tên tiềm ẩn. Với phương thức này, mỗi tên lớp cần phải là duy nhất trên tất cả các thành phần.

Để khám phá vấn đề này, bạn sẽ thực hiện một số thay đổi đối với thành phần Alert .

Đầu tiên, hãy mở file :

  • nano src/components/Alert/Alert.js

Sau đó, thêm một số mã React sẽ lấy children , typetitle làm đạo cụ:

style-tutorial / src / components / Alert / Alert.js
import React from 'react'; import PropTypes from 'prop-types';  export default function Alert({ children, title, type }) {   return (     <div>       <h2>{title}</h2>       {children}     </div>   ) }  Alert.propTypes = {   children: PropTypes.oneOfType([     PropTypes.arrayOf(PropTypes.element),      PropTypes.element.isRequired   ]),   title: PropTypes.string.isRequired,   type: PropTypes.string.isRequired, } 

title trong mã này nằm trong <h2> và phần tử children sẽ cho phép bạn hiển thị các thành phần con. Bạn sẽ sớm sử dụng type prop để đặt thành công và cảnh báo lỗi dựa trên hệ thống gõ PropTypes .

Lưu và đóng file . Tiếp theo, cập nhật thành phần Alert trong App để sử dụng các đạo cụ mới.

Đầu tiên, hãy mở App.js :

  • nano src/components/App/App.js

Tạo cảnh báo thông báo cho user rằng nỗ lực thêm các mặt hàng vào giỏ hàng đã không thành công:

style-tutorial / src / components / App / App.js
import React from 'react'; import './App.css';  import Alert from '../Alert/Alert';  function App() {   return (     <div className="wrapper">       <Alert title="Items Not Added" type="error">         <div>Your items are out of stock.</div>       </Alert>     </div>   ) }  export default App; 

Trong mã này, bạn đã cập nhật title và phần children với thông báo lỗi, sau đó thêm một type error .

Lưu và đóng file . Khi bạn làm như vậy, trình duyệt sẽ làm mới và bạn sẽ thấy thành phần mới của bạn :

Thành phần cảnh báo

Cảnh báo của bạn đang hiển thị, vì vậy bước tiếp theo là tạo kiểu cho thành phần bằng CSS.

Thêm CSS vào thành phần Alert

Vì thành phần Alert báo hiển thị lỗi, bạn sẽ thêm đường viền và đặt màu của đường viền thành màu đỏ. Bạn cũng sẽ cung cấp cho <h2> cùng một màu. Nhưng điều này gây ra một vấn đề: Bạn không thể sử dụng wrapper tên trên <div> bên ngoài trong thành phần Alert của bạn , vì tên đó đã được thành phần App .

Xung đột tên lớp không phải là một vấn đề mới trong CSS và đã có một số nỗ lực để giải quyết nó bằng cách sử dụng các quy ước đặt tên như BEM . Nhưng các quy ước đặt tên có thể trở nên dài dòng và đôi khi vẫn có thể dẫn đến xung đột trong các dự án có nhiều thành phần.

Thay vì sử dụng một bộ luật cụ thể được phân tách bằng quy ước đặt tên, trong hướng dẫn này, bạn sẽ đặt tiền tố tên lớp wrapper với tên của thành phần. Tên lớp mới của bạn sẽ là alert-wrapper . Ngoài ra, bạn sẽ thêm type cảnh báo dưới dạng một lớp.

Mở thành phần Alert :

  • nano src/components/Alert/Alert.js

Tiếp theo, thêm mã được đánh dấu sau:

style-tutorial / src / components / Alert / Alert.js
import React from 'react'; import PropTypes from 'prop-types'; import './Alert.css'; ... export default function Alert({ children, type, title }) {   return(     <div className={`alert-wrapper ${type}`}>       <h2>{title}</h2>       {children}     </div>   ) } ... 

Trong trường hợp này, bạn đang kết hợp alert-wrapper và biến type thành một chuỗi duy nhất bằng cách sử dụng ký tự mẫu .

Lưu và đóng file . Đến đây bạn có một tên lớp duy nhất có thể thay đổi động dựa trên giá đỡ. JSX trong mã này sẽ phân giải thành một div với các tên lớp của alert-wrappererror . Đánh dấu đã biên dịch sẽ là: <div class="alert-wrapper error"> .

Bây giờ thêm các phong cách. Đầu tiên, hãy mở CSS cho thành phần Alert :

  • nano src/components/Alert/Alert.css

Thêm CSS sau vào các lớp alert-wrapper , successerror :

style-tutorial / src / components / Alert / Alert.css
 .alert-wrapper {     padding: 15px;     margin-bottom: 15px; }  .alert-wrapper h2 {     margin: 0 0 10px 0; }  .alert-wrapper.success {     border: #6DA06F solid 1px; }  .success h2 {     color: #6DA06F; }  .alert-wrapper.error {     border: #F56260 solid 1px; }  .error h2 {     color: #F56260; } 

Mã này thêm một số lề và phần đệm vào alert-wrapper . Sau đó, nó thêm một đường viền có màu đỏ cho lớp error bằng cách sử dụngmã màu hệ #F56260 và một bóng màu xanh lá cây ( #6DA06F ) cho lớp success . Nó cũng cập nhật màu <h2> thành đỏ hoặc xanh lá cây tùy thuộc vào phụ huynh.

Lưu và đóng file . Khi bạn làm như vậy, trình duyệt sẽ làm mới và bạn sẽ thấy các kiểu mới:

Cảnh báo lỗi theo kiểu

Đến đây bạn đã có thành phần Alert được tạo kiểu, bạn có thể tạo một thành phần mới hiển thị danh sách các mục trong thành phần Alert . Vì bọn trẻ sẽ phức tạp hơn nên sẽ có nhiều khả năng xảy ra xung đột phong cách hơn.

Tạo thành phần thông báo thành công

Đầu tiên, tạo một folder cho thành phần mới CartSuccess :

  • mkdir src/components/CartSuccess

Mở CartSuccess.js :

  • nano src/components/CartSuccess/CartSuccess.js

Bên trong thành phần, hãy nhập thành phần Alert và chuyển một <div> chứa một loạt các mặt hàng mà user đã thêm vào giỏ hàng:

style-tutorial / src / components / CartSuccess / CartSuccess.js
import React from 'react'; import Alert from '../Alert/Alert'; import './CartSuccess.css';  export default function CartSuccess() {   return(     <Alert title="Added to Cart" type="success">       <div className="cart-success-wrapper">           <h2>             You have added 3 items:           </h2>           <div className="item">             <div>Bananas</div>             <div>Quantity: 2</div>           </div>           <div className="item">             <div>Lettuce</div>             <div>Quantity: 1</div>           </div>       </div>     </Alert>   ) } 

Lưu ý cách bạn cần để tạo một tên lớp duy nhất— cart-success-wrapper —cho <div> bên ngoài. Lưu và đóng file .

Tiếp theo, thêm một số CSS vào thông báo tùy chỉnh. Mở CartSuccess.css :

  • nano src/components/CartSuccess/CartSuccess.css

Thêm display flex vào wrapper. Bạn cần hầu hết các mục được bao bọc, ngoại trừ phần tử <h2> , sẽ chiếm toàn bộ chiều rộng:

style-tutorial / src / components / CartSuccess / CartSuccess.css
.cart-success-wrapper {     border-top: black solid 1px;     display: flex;     flex-wrap: wrap; }  .cart-success-wrapper h2 {     width: 100%; }  .item {     margin-right: 20px; } 

Ở đây, bạn đã cho <h2> chiều rộng là 100% . Ngoài việc làm linh hoạt phần tử, bạn cũng đã thêm một đường viền nhỏ vào đầu thư và thêm một lề vào lớp item để cung cấp một số khoảng cách giữa các mục.

Lưu và đóng file .

Đến đây bạn đã có một thành phần được tạo kiểu, hãy thêm nó vào thành phần App của bạn.

Mở App.js :

  • nano src/components/App/App.js

Nhập thành phần và thêm thành phần đó sau thành phần Alert hiện tại, như trong mã được đánh dấu:

style-tutorial / src / components / App / App.js
import React from 'react'; import './App.css';  import Alert from '../Alert/Alert'; import CartSuccess from '../CartSuccess/CartSuccess';  function App() {   return(     <div className="wrapper">       <Alert title="Items Not Added" type="error">         <div>Your items are out of stock.</div>       </Alert>       <CartSuccess />     </div>   ) }  export default App; 

Lưu và đóng file . Khi bạn làm như vậy, trình duyệt sẽ làm mới và bạn sẽ thấy thành phần mới của bạn :

Cảnh báo trong ứng dụng

Điều này hiển thị màu mới và thông báo như dự định, nhưng thành phần lồng nhau nhận được một số kiểu không mong muốn. Luật cho <h2> trong thành phần Alert đang được áp dụng cho <h2> lồng nhau trong đạo cụ children .

Các kiểu xếp tầng không mong muốn đối với trẻ em là một vấn đề phổ biến với CSS. Tuy nhiên, vì React cung cấp cho bạn cơ hội để group và chia sẻ các thành phần trong các dự án, bạn có nhiều khả năng hơn để các kiểu vô tình chuyển xuống các thành phần con.

Để khắc phục điều này bằng CSS thuần túy, hãy đặt luật <h2> cho thành phần Alert cụ thể hơn một chút.

Mở file Alert.css :

  • nano src/components/Alert/Alert.css

Thay đổi các luật để kiểu <h2> chỉ áp dụng cho các lớp con trực tiếp thay vì tất cả các lớp con sử dụng bộ tổ hợp con CSS > :

style-tutorial / src / components / Alert / Alert.css
.alert-wrapper {     padding: 15px;     margin-bottom: 15px; }  .alert-wrapper > h2 {     margin: 0 0 10px 0; }  .alert-wrapper.success {     border: #6da06f solid 1px; }  .success > h2 {     color: #6da06f; }  .alert-wrapper.error {     border: #f56260 solid 1px; }  .error > h2 {     color: #f56260; } 

Lưu và đóng file . Khi bạn làm như vậy, trang sẽ làm mới và bạn sẽ thấy phần tử <h2> trong CartSuccess vẫn giữ màu mặc định:

H2 có màu sẫm

Như vậy, các kiểu cho thành phần Alert sẽ chỉ ảnh hưởng đến các node con ngay lập tức và sẽ không áp dụng cho các node hoặc thành phần con khác. Phương pháp này hoạt động tốt trong trường hợp này, nhưng trong trường hợp các thành phần phức tạp hơn, có thể khó viết các luật áp dụng cho tất cả các trường hợp mà không bị rò rỉ bên ngoài thành phần.

Trong bước này, bạn đã tạo kiểu cho một thành phần bằng cách sử dụng bảng định kiểu CSS được nhập trực tiếp vào một thành phần. Tạo kiểu cho các phần tử React với CSS chuẩn là một cách nhanh chóng để tạo các thành phần với các kiểu được liên kết bằng cách sử dụng các file CSS chuẩn. Tính dễ sử dụng khiến nó trở thành bước đầu tiên tốt khi bạn đang làm việc với các dự án mới hoặc nhỏ, nhưng khi các dự án phát triển, nó có thể gây ra vấn đề.

Khi bạn xây dựng các thành phần, bạn gặp phải hai vấn đề về kiểu dáng phổ biến: xung đột tên lớp và ứng dụng kiểu không mong muốn. Bạn có thể giải quyết chúng bằng CSS chuẩn, nhưng có những cách tiếp cận tạo kiểu khác cung cấp cho bạn các công cụ để xử lý những vấn đề này theo chương trình thay vì bằng các quy ước đặt tên. Trong bước tiếp theo, bạn sẽ khám phá việc giải quyết những vấn đề này với các đối tượng kiểu.

Bước 3 - Tạo kiểu với các đối tượng kiểu

Trong bước này, bạn sẽ tạo kiểu cho các thành phần của bạn bằng cách sử dụng các đối tượng kiểu , là các đối tượng JavaScript sử dụng thuộc tính CSS làm khóa. Khi bạn làm việc trên các thành phần của bạn , bạn sẽ cập nhật các khóa để trùng với cú pháp JavaScript và tìm hiểu cách đặt động các thuộc tính kiểu dựa trên các đạo cụ thành phần.

CSS riêng biệt là cách phổ biến nhất để tạo kiểu HTML. Phương pháp này nhanh và các trình duyệt có hiệu quả trong việc áp dụng các kiểu một cách nhanh chóng và nhất quán. Nhưng đây không phải là lựa chọn duy nhất để tạo kiểu HTML. Trong HTML chuẩn, bạn có thể đặt các kiểu nội tuyến trực tiếp trên một phần tử bằng cách sử dụng thuộc tính style với một chuỗi chứa các kiểu bạn muốn áp dụng.

Một trong những cách sử dụng tốt nhất của đối tượng kiểu là để tính toán kiểu động. Điều này đặc biệt hữu ích nếu bạn cần biết vị trí hiện tại của phần tử, vì điều này không được xác định cho đến khi các phần tử được hiển thị và do đó chỉ có thể được xử lý động.

Việc viết chuỗi kiểu thủ công rất khó thực hiện và có thể gây ra lỗi. Thiếu màu hoặc dấu chấm phẩy sẽ làm đứt toàn bộ chuỗi. May mắn là trong JSX, bạn không bị giới hạn chỉ trong một chuỗi. Thuộc tính style cũng có thể chấp nhận một đối tượng chứa các style. Những tên kiểu này cần phải là camelCase chứ không phải là kebab-case .

Ưu điểm lớn nhất của việc sử dụng các kiểu nội tuyến như thế này là, vì bạn đang xây dựng kiểu bằng JavaScript, bạn có thể đặt động các thuộc tính CSS thay vì đặt động các lớp. Điều này nghĩa là bạn có thể viết mã mà không cần các lớp CSS, tránh mọi xung đột tên tiềm ẩn và cho phép bạn tính toán các kiểu trong thời gian chạy.

Để sử dụng các đối tượng kiểu, hãy bắt đầu bằng cách cấu trúc lại App.js Đầu tiên, hãy mở file :

  • nano src/components/App/App.js

Bên trong thành phần, hãy xóa file App.css nhập, sau đó tạo một đối tượng có khoảng padding 20 và chuyển đối tượng vào <div> bằng cách sử dụng thuộc tính style :

style-tutorial / src / components / App / App.js
import React from 'react';  import Alert from '../Alert/Alert'; import CartSuccess from '../CartSuccess/CartSuccess';  function App() {   const wrapper = {     padding: 20   };    return(     <div style={wrapper}>       <Alert title="Items Not Added" type="error">         <div>Your items are out of stock.</div>       </Alert>       <CartSuccess />     </div>   ) }  export default App; 

Lưu ý bạn không phải chỉ định pixel làm đơn vị cho phần padding . React sẽ chuyển đổi nó thành một chuỗi pixel theo mặc định. Nếu bạn muốn một đơn vị cụ thể, hãy chuyển nó dưới dạng một chuỗi. Vì vậy, nếu bạn muốn padding là một tỷ lệ phần trăm, chẳng hạn, nó sẽ là padding: '20%' .

Hầu hết các số sẽ được tự động chuyển đổi thành pixel. Tuy nhiên, vẫn có những ngoại lệ. line-height có thể nhận dạng số thuần túy mà không có đơn vị . Nếu bạn muốn sử dụng đơn vị pixel trong trường hợp đó, bạn cần chỉ định pixel dưới dạng chuỗi.

Lưu và đóng file . Khi bạn làm như vậy, trình duyệt sẽ làm mới và bạn sẽ thấy trang như trước đây:

Trang có đối tượng kiểu

Tiếp theo, cấu trúc lại CartSuccess Đầu tiên, hãy mở file :

  • nano src/components/CartSuccess/CartSuccess.js

Cũng như với App.js , hãy xóa CSS đã nhập ( CartSuccess.css ) và tạo một đối tượng kiểu cho từng mục mà trước đó có một lớp:

style-tutorial / src / components / CartSuccess / CartSuccess.js
import React from 'react'; import Alert from '../Alert/Alert';  export default function CartSuccess() {   const styles = {     header: {       width: '100%'     },     item: {       marginRight: 20     },     wrapper: {       borderTop: 'black solid 1px',       display: 'flex',       flexWrap: 'wrap'     }   }    return(     <Alert title="Added to Cart" type="success">       <div style={styles.wrapper}>           <h2 style={styles.header}>             You have added 3 items:           </h2>           <div style={styles.item}>             <div>Bananas</div>             <div>Quantity: 2</div>           </div>           <div style={styles.item}>             <div>Lettuce</div>             <div>Quantity: 1</div>           </div>       </div>     </Alert>   ) } 

Trong trường hợp này, bạn đã không tạo nhiều đối tượng riêng biệt; thay vào đó, bạn đã tạo một đối tượng duy nhất chứa các đối tượng khác. Cũng lưu ý bạn cần sử dụng trường hợp lạc đà cho các thuộc tính của margin-right , border-topflex-wrap .

Lưu và đóng file . Khi bạn làm như vậy, trang sẽ làm mới và bạn sẽ thấy trang có cùng kiểu:

Trang có đối tượng kiểu

Vì bạn không sử dụng các lớp, bạn không phải lo lắng về bất kỳ xung đột tên nào. Một lợi thế khác của việc tạo kiểu bằng JavaScript là bạn có thể tận dụng bất kỳ cú pháp JavaScript nào như các biến và các ký tự mẫu. Với CSS hiện đại, bạn có thể sử dụng các biến , đây là một cải tiến lớn, nhưng có thể không khả dụng đầy đủ tùy thuộc vào yêu cầu hỗ trợ trình duyệt của bạn. Đặc biệt, chúng không được hỗ trợ trong bất kỳ version nào của Internet Explorer, mặc dù bạn có thể sử dụng polyfill để thêm hỗ trợ.

Vì các đối tượng kiểu được tạo trong thời gian chạy, chúng dễ dự đoán hơn và có thể sử dụng bất kỳ JavaScript nào được hỗ trợ.

Để xem các đối tượng kiểu có thể trợ giúp như thế nào trong trường hợp này, hãy cấu trúc lại Alert.js để sử dụng các đối tượng kiểu. Đầu tiên, hãy mở Alert.js :

  • nano src/components/Alert/Alert.js

Bên trong Alert.js , hãy xóa import './Alert.css'; và tạo một đối tượng gọi là colors có thuộc tính cho màu lỗi và một thuộc tính cho màu thành công. Sau đó, chuyển đổi CSS thành một đối tượng JavaScript bằng cách sử dụng type prop để đặt động màu:

style-tutorial / src / components / Alert / Alert.js
import React from 'react'; import PropTypes from 'prop-types';  export default function Alert({ children, type, title }) {   const colors = {     success: '#6da06f',     error: '#f56260',   }    const style = {     heading: {       color: colors[type],       margin: '0 0 10px 0',     },     wrapper: {       border: `${colors[type]} solid 1px`,       marginBottom: 15,       padding: 15,       position: 'relative',     }   }    return(     <div style={style.wrapper}>       <h2 style={style.heading}>{title}</h2>       {children}     </div>   ) }  ... 

Có một vài thay đổi ở đây. Đầu tiên, bạn sử dụng một khai báo kiểu duy nhất cho wrapper và sau đó đặt động màu dựa trên kiểu. Bạn không tạo kiểu cho các phần tử <h2> nói chung, nhưng thay vào đó bạn đang tạo kiểu cho các phần tử cụ thể này, tình cờ là các phần tử <h2> . Vì bạn không áp dụng kiểu cho một kiểu phần tử, nên không có gì nguy hiểm khi kiểu sẽ chảy xuống các phần tử con.

Lưu và đóng file . Khi bạn làm như vậy, trình duyệt sẽ làm mới và bạn sẽ thấy các kiểu được áp dụng.

Trang có đối tượng kiểu

Đối tượng kiểu giải quyết nhiều vấn đề, nhưng chúng có nhược điểm. Đầu tiên, có một chi phí hiệu suất cho các kiểu nội tuyến . Các trình duyệt được thiết kế để xử lý CSS một cách hiệu quả và các đối tượng tạo kiểu áp dụng kiểu nội tuyến không thể tận dụng những tối ưu hóa này. Vấn đề khác là việc áp dụng kiểu cho các phần tử con với các đối tượng kiểu sẽ khó hơn. Trong trường hợp này, bạn không muốn một kiểu áp dụng cho trẻ em, nhưng thường là bạn muốn kiểu xếp tầng. Ví dụ: đặt họ phông chữ tùy chỉnh trên mọi phần tử hoặc áp dụng kích thước tùy chỉnh cho mọi phần tử <h2> sẽ dễ dàng hơn nếu bạn sử dụng chiến lược tạo kiểu ít cụ thể hơn.

Tuy nhiên, có một điểm trung gian giữa những cách tiếp cận này. Một số thư viện của bên thứ ba được thiết kế để tìm điểm trung gian này. Trong bước tiếp theo, bạn sẽ tạo kiểu bằng cách sử dụng phương pháp kết hợp có tên là CSS-in-JS bằng cách sử dụng một thư viện có tên là JSS.

Bước 4 - Tạo kiểu với JSS

Trong bước này, bạn sẽ tạo kiểu cho các đối tượng bằng cách sử dụng thư viện phổ biến JSS . Bạn sẽ cài đặt thư viện mới và chuyển đổi các đối tượng kiểu của bạn thành các đối tượng JSS. Sau đó, bạn sẽ cấu trúc lại mã của bạn để sử dụng các tên lớp được tạo động để ngăn chặn xung đột giữa các tên lớp giữa các module . Bạn cũng sẽ xây dựng các đối tượng kiểu JavaScript có thể đặt kiểu động và sử dụng các thuộc tính lồng nhau để tạo các luật kiểu cụ thể.

JSS là một thư viện để tạo CSS-in-JS. Phương pháp này có nhiều trường hợp sử dụng và tùy chọn khác nhau , nhưng ưu điểm chính trong hướng dẫn này là nó sẽ tạo ra các tên lớp động để tránh xung đột giữa các thành phần. Bạn cũng sẽ có thể tận dụng cú pháp JavaScript, nghĩa là bạn có thể sử dụng các biến và tạo kiểu dựa trên các đạo cụ React.

Để bắt đầu, hãy cài đặt phiên bản JSS cụ thể của React . Hướng dẫn này sẽ sử dụng version 10.1.1 :

  • npm install react-jss

Gói sẽ cài đặt một số phụ thuộc, bao gồm một số plugin JSS sẽ cung cấp cho bạn khả năng viết các luật kiểu ngắn gọn.

Khi quá trình cài đặt hoàn tất, bạn sẽ thấy thông báo thành công:

Output
+ react-jss@10.1.1 added 281 packages from 178 contributors, removed 142 packages, updated 1392 packages and audited 1025251 packages in 144.872s

Đầu ra của bạn sẽ thay đổi một chút tùy thuộc vào version Node của bạn và các phụ thuộc khác.

Bây giờ thư viện đã được cài đặt, hãy chuyển đổi App.js để sử dụng JSS. Đầu tiên, hãy mở App.js :

  • nano src/components/App/App.js

Có hai bước để sử dụng JSS. Đầu tiên, bạn phải nhập một hàm để tạo một hook tùy chỉnh . Hook là các hàm mà React sẽ chạy trên mọi thành phần render. Với JSS, bạn phải tạo một hook bằng cách chuyển các định nghĩa kiểu vào bên ngoài thành phần. Điều này sẽ ngăn mã chạy trên mỗi lần hiển thị lại; vì các định nghĩa kiểu là tĩnh, không có lý do gì để chạy mã thêm .

Tạo hook và đối tượng kiểu bằng cách áp dụng các thay đổi được đánh dấu:

style-tutorial / src / components / App / App.js
import React from 'react'; import { createUseStyles } from 'react-jss';  import Alert from '../Alert/Alert'; import CartSuccess from '../CartSuccess/CartSuccess';  const useStyles = createUseStyles({   wrapper: {     padding: 20,   } });  function App() {   return(     <div>       <Alert title="Items Not Added" type="error">         <div>Your items are out of stock.</div>       </Alert>       <CartSuccess />     </div>   ) }  export default App; 

Lưu ý trong trường hợp này đối tượng kiểu của bạn chứa một đối tượng khác được gọi là wrapper , chứa các kiểu sử dụng cùng một định dạng trường hợp lạc đà. Tên của đối tượng— wrapper — là cơ sở để tạo tên lớp động.

Sau khi bạn tạo hook, bạn sử dụng nó bằng cách thực thi chức năng bên trong thành phần. Điều này đăng ký hook và tạo kiểu động. Thực hiện thay đổi được đánh dấu sau:

style-tutorial / src / components / App / App.js
import React from 'react'; import { createUseStyles } from 'react-jss'  import Alert from '../Alert/Alert'; import CartSuccess from '../CartSuccess/CartSuccess';  const useStyles = createUseStyles({   wrapper: {     padding: 20,   } });  function App() {   const classes = useStyles()   return(     <div className={classes.wrapper}>       <Alert title="Items Not Added" type="error">         <div>Your items are out of stock.</div>       </Alert>       <CartSuccess />     </div>   ) }  export default App; 

Trong đoạn mã này, bạn gọi hàm và gán kết quả cho một biến được gọi là classes . Các classes biến mới sẽ là một đối tượng chứa tên lớp động. Sau đó, bạn áp dụng tên lớp thích hợp cho phần tử của bạn bằng cách sử dụng cùng tên mà bạn đã xác định trên đối tượng. Ở đây bạn đã sử dụng classes.wrapper .

Lưu và đóng file . Khi bạn thực hiện, trình duyệt sẽ làm mới và bạn sẽ thấy các kiểu giống như trước đây. Nhưng nếu bạn nhìn vào console , bạn sẽ thấy rằng tên lớp không hoàn toàn trùng với tên bạn đã xác định trong đối tượng của bạn :

Kiểu có tên lớp được áp dụng

Trong trường hợp này, tên lớp là wrapper-0-2-1 , nhưng tên lớp của bạn có thể khác. Bạn cũng sẽ thấy rằng các kiểu được chuyển đổi từ một đối tượng sang CSS và được đặt trong <style> . Đối lập điều này với các kiểu nội tuyến, không được chuyển đổi sang CSS và không có bất kỳ tên lớp nào.

JSS tạo động các tên lớp để chúng không xung đột với các tên tương tự trong các file khác. Để xem điều này tại nơi làm việc, hãy cấu trúc lại CartSuccess.js để sử dụng kiểu JSS.

Mở tập tin:

  • nano src/components/CartSuccess/CartSuccess.js

Bên trong file , tạo một móc tùy chỉnh bằng cách sử dụng createUseStyles . Thay vì áp dụng một lớp cho phần tử <h2> , bạn sẽ tạo luật cho các phần tử <h2> bên trong shell bọc. Để làm điều đó với CSS thuần túy, bạn thêm khoảng trắng giữa lớp và phần tử— .wrapper h2 . Điều này áp dụng kiểu cho tất cả các phần tử <h2> là con của lớp .wrapper .

Với JSS, bạn có thể tạo một luật tương tự bằng cách tạo một đối tượng khác bên trong phần tử chứa. Để liên kết chúng, hãy bắt đầu tên đối tượng bằng ký hiệu & :

style-tutorial / src / components / CartSuccess / CartSuccess.js
import React from 'react'; import { createUseStyles } from 'react-jss'; import Alert from '../Alert/Alert';  const useStyles = createUseStyles({   item: {     marginRight: 20   },   wrapper: {     borderTop: 'black solid 1px',     display: 'flex',     flexWrap: 'wrap',     '& h2': {       width: '100%'     }   } })  export default function CartSuccess() {   const classes = useStyles();   return(     <Alert title="Added to Cart" type="success">       <div className={classes.wrapper}>           <h2>             You have added 3 items:           </h2>           <div className={classes.item}>             <div>Bananas</div>             <div>Quantity: 2</div>           </div>           <div className={classes.item}>             <div>Lettuce</div>             <div>Quantity: 1</div>           </div>       </div>     </Alert>   ) } 

Ngoài việc tạo luật cho shell bọc, bạn cũng tạo luật cho item . Sau khi tạo móc tùy chỉnh, bạn đã chuyển các tên lớp tùy chỉnh vào thuộc tính className .

Lưu các file . Lưu ý bạn đang sử dụng cùng một tên— wrapper — trong cả thành phần này và thành phần App . Nhưng khi trình duyệt reload , sẽ không có xung đột đặt tên; mọi thứ sẽ chính xác. Nếu bạn kiểm tra các phần tử trong trình duyệt của bạn , bạn sẽ thấy rằng mặc dù chúng bắt đầu bằng cùng một tên, nhưng chúng đều có một lớp duy nhất:

Hình ảnh với nhiều lớp  shell  bọc

Trong trường hợp này, lớp cho thành phần bên ngoài là wrapper-0-2-1 , được tạo trong thành phần App . Lớp cho CartSuccesswrapper-0-2-3 . Tên thành phần của bạn có thể hơi khác, nhưng chúng sẽ là duy nhất.

Trong một số trường hợp, bạn có thể cần tạo một bộ chọn cụ thể để overrides các kiểu khác. Ví dụ: giả sử bạn chỉ muốn áp dụng kiểu dáng item khi phần tử là con của lớp wrapper . Để làm điều này, trước tiên hãy tạo lớp trên đối tượng không có thuộc tính nào. Sau đó, bên trong lớp wrapper , tham chiếu đến lớp mới bằng ký hiệu $ :

style-tutorial / src / components / CartSuccess / CartSuccess.js
import React from 'react'; import { createUseStyles } from 'react-jss' import Alert from '../Alert/Alert';  const useStyles = createUseStyles({   item: {},   wrapper: {     borderTop: 'black solid 1px',     display: 'flex',     flexWrap: 'wrap',     '& h2': {       width: '100%'     },     '& $item': {       marginRight: 20     }   } })  export default function CartSuccess() {   const classes = useStyles()   return(     <Alert title="Added to Cart" type="success">       <div className={classes.wrapper}>           <h2>             You have added 3 items:           </h2>           <div className={classes.item}>             <div>Bananas</div>             <div>Quantity: 2</div>           </div>           <div className={classes.item}>             <div>Lettuce</div>             <div>Quantity: 1</div>           </div>       </div>     </Alert>   ) } 

Lưu và đóng file . Khi trình duyệt reload , trang sẽ trông giống nhau, nhưng CSS của item sẽ được áp dụng cụ thể hơn cho các mục trong thành phần shell bọc:

Đã áp dụng hạng mục

JSS cung cấp cho bạn khả năng tạo các luật có cùng mức độ trọng tâm mà bạn tạo với CSS thông thường, nhưng sẽ làm như vậy trong khi tạo các tên lớp duy nhất không đụng độ.

Một lợi thế cuối cùng của JSS là bạn có khả năng sử dụng các biến và các tính năng ngôn ngữ JavaScript khác. Vì bạn đang sử dụng react-jss , bạn có thể chuyển các đạo cụ cho đối tượng kiểu để tạo kiểu động. Để kiểm tra điều này, hãy cấu trúc lại thành phần Alert.js để sử dụng các đạo cụ và biến để tạo thuộc tính động.

Đầu tiên, hãy mở file :

  • nano src/components/Alert/Alert.js

Tạo một đối tượng kiểu giống như bạn đã làm trong mã đã cấu trúc lại lần trước. Đảm bảo di chuyển đối tượng xác định màu sắc bên ngoài hàm thành phần để nó nằm trong cùng phạm vi với hàm createUseStyles :

style-tutorial / src / components / Alert / Alert.js
import React from 'react'; import PropTypes from 'prop-types'; import { createUseStyles } from 'react-jss';  const colors = {   success: '#6da06f',   error: '#f56260', };  const useStyles = createUseStyles({     wrapper: {       border: ({ type }) => `${colors[type]} solid 1px`,       marginBottom: 15,       padding: 15,       position: 'relative',       '& h2': {         color: ({ type }) => colors[type],         margin: [0, 0, 10, 0],       }     } });  export default function Alert({ children, type, title }) {   const classes = useStyles({ type })   return(     <div className={classes.wrapper}>       <h2>{title}</h2>       {children}     </div>   ) }  ... 

Để chuyển đạo cụ, bạn đặt luật kiểu thành một hàm. Hàm chấp nhận đạo cụ làm đối số sau đó trả về luật . Để tạo đường viền động, bạn thêm border làm tên thuộc tính và hàm mũi tên nhận type và trả về chuỗi: ({ type }) => `${colors[type]} solid 1px`, . Sau đó, sau khi bạn tạo hook của bạn , bạn chuyển các đạo cụ mà bạn muốn tham chiếu khi tạo đối tượng lớp. Như trước đây, bạn định kiểu <h2> theo phần tử thay vì tạo một lớp cụ thể. Bạn cũng chuyển một mảng giá trị cho margin thay vì một chuỗi chẳng hạn như 0px 0px 10px 10px .

Lưu các file . Lưu ý bạn không cần phải chuyển tất cả các đạo cụ vào hàm. Trong trường hợp này, bạn chỉ muốn sử dụng type , vì vậy đó là tất cả những gì bạn cần vượt qua. Tuy nhiên, bạn có thể vượt qua nhiều hơn hoặc thậm chí vượt qua các đạo cụ không xác định bằng cách sử dụng toán tử còn lại để thu thập các đạo cụ và sau đó chuyển chúng thành một group . Bạn cần phải chuyển nó như một đối tượng; tuy nhiên, vì đó là cách tiêu chuẩn để chuyển các đạo cụ, nó sẽ giúp việc mở rộng đối số dễ dàng hơn trong tương lai.

Khi reload trang, bạn sẽ thấy các màu chính xác, nhưng sẽ có một vấn đề nhỏ: màu thành công xanh hiện đang cập nhật phần tử <h2> trong CartSuccess :

H2 có màu xanh lục

JSS giải quyết nhiều vấn đề, nhưng nó vẫn tạo ra CSS chuẩn. Điều đó nghĩa là các kiểu có thể áp dụng cho các phần tử con nếu bạn không cẩn thận. Để khắc phục điều này, hãy thêm biểu tượng > để làm cho CSS chỉ áp dụng cho các phần tử con trực tiếp:

style-tutorial / src / components / Alert / Alert.js
import React from 'react'; ... const useStyles = createUseStyles({     wrapper: {       border: ({ type }) => `${colors[type]} solid 1px`,       marginBottom: 15,       padding: 15,       position: 'relative',       '& > h2': {         color: ({ type }) => colors[type],         margin: [0, 0, 10, 0],       }     } });  export default function Alert({ children, type, title }) {  ...  }  ... 

Lưu và đóng file . Khi bạn thực hiện, trình duyệt sẽ reload và bạn sẽ thấy các kiểu chính xác:

H2 có màu sẫm

Còn nhiều hơn nữa về JSS ngoài những gì được đề cập trong hướng dẫn này. Một lợi thế quan trọng mà ta chưa đề cập đến là theming . JSS cung cấp cho bạn khả năng tạo kiểu dựa trên các đối tượng chủ đề được định nghĩa . Điều đó nghĩa là thay vì tạo màu đỏ từ một giá trị được mã hóa cứng, bạn có thể đặt đường viền alert màu alert , có thể sẽ là màu đỏ, nhưng có thể khác tùy thuộc vào định nghĩa chủ đề. Điều này hữu ích khi tạo các sản phẩm nhãn trắng hoặc tạo các thành phần có thể tái sử dụng cần hoạt động trong các dự án.

Trong bước này, bạn đã tạo kiểu cho các thành phần bằng cách sử dụng thư viện của bên thứ ba có tên là react-jss . Bạn cũng đã tạo đối tượng kiểu và sử dụng JSS để chuyển đổi các đối tượng đó thành các lớp động để tránh xung đột với các thành phần khác. Sử dụng phương pháp này, bạn có thể sử dụng lại các tên lớp đơn giản một cách an toàn mà không phải lo lắng về xung đột sau này trong mã. Cuối cùng, bạn đã học cách tạo kiểu bằng cách sử dụng các hàm và đạo cụ để tạo kiểu động tham chiếu đến các đạo cụ thành phần.

Kết luận

Trong suốt hướng dẫn này, bạn đã phát triển một số thành phần có thể tái sử dụng sử dụng các kỹ thuật kiểu khác nhau. Bạn đã học cách các đối tượng kiểu và JSS tạo các đối tượng bằng cách sử dụng các tên phản ánh chặt chẽ các thuộc tính CSS chuẩn và đã tạo các thành phần có thể đặt kiểu động dựa trên các thuộc tính đến. Bạn cũng đã học cách các cách tiếp cận khác nhau cung cấp các tùy chọn khác nhau để xử lý xung đột tên và khả năng tái sử dụng.

Như với hầu hết các kỹ thuật React, không có giải pháp tốt nhất duy nhất. Thay vào đó, bạn có thể chọn tùy chọn tạo kiểu phù hợp nhất cho dự án của bạn . Với những tùy chọn này trong tay, bạn có thể bắt đầu với một cái gì đó đơn giản và tái cấu trúc khi dự án phát triển hoặc các yêu cầu thay đổi, trong khi vẫn tự tin rằng các thành phần của bạn sẽ tiếp tục đáp ứng các mục tiêu phong cách của bạn.

Nếu bạn muốn xem thêm các hướng dẫn về React, hãy xem trang Chủ đề React của ta hoặc quay lại trang Cách viết mã trong chuỗi React.js .


Tags:

Các tin liên quan