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

Giới thiệu về React Hooks


Các thành phần chức năng rất tuyệt vời, nhưng chúng bị hạn chế để thực hiện chính xác những gì chúng được yêu cầu bởi các thuộc tính. Thời điểm bạn cần chúng lưu ý đến trạng thái của chúng, bạn buộc phải viết lại chúng dưới dạng các thành phần lớp. May mắn là rất nhiều tính năng chỉ dành cho thành phần lớp đang thực hiện theo cách của chúng để vận hành các thành phần.

Một tính năng như vậy, hiện đang ở giai đoạn alpha và dự kiến sẽ xuất hiện trong React v16.7, là Hooks . Hooks mang đến các phương thức trạng thái và vòng đời, trước đây chỉ có sẵn cho các thành phần lớp đến các thành phần chức năng.

Bắt đầu

Như đã đề cập, tính năng này hiện đang ở giai đoạn alpha nhưng dự kiến sẽ là một phần trong bản phát hành điểm tiếp theo của React. Do đó, ta cần chỉ định một version khi thêm React vào dự án của bạn .

# Via npm
$ npm install --save react@next react-dom@next

# Or via Yarn
$ yarn add react@next react-dom@next

Điều gì tạo nên một Hook?

  • Phải bắt đầu với việc use từ.
  • Hooks chỉ có thể được gọi từ bên trong các thành phần chức năng và Hooks tùy chỉnh. Điều này có lợi ích bổ sung là giữ logic thành phần của bạn được group lại với nhau một cách độc đáo.
  • Chỉ sử dụng Hook ở cấp cao nhất, không bao giờ sử dụng bên trong các điều kiện, vòng lặp hoặc các hàm lồng nhau trong thành phần hàm của bạn. Điều này giúp đảm bảo các Hook được gọi theo cùng một thứ tự với mỗi lần hiển thị.

Trạng thái thành phần

Để tạo một thành phần chức năng trạng thái bằng Hooks, ta cần khởi tạo trạng thái bằng useState từ gói React.

Phương thức này chấp nhận một tham số để đặt trạng thái ban đầu và trả về một mảng chứa trạng thái hiện tại và một hàm để đặt trạng thái.

Đây là một thành phần chức năng trạng thái theo dõi màu được đặt ngẫu nhiên mỗi khi nhấn nút:

import React, { useState } from "react";
import { render } from "react-dom";

function StatefulFn() {
  const [color, setColor] = useState(false);

  function onClick() {
    const colors = [
      "#008F68",
      "#6DB65B",
      "#4AAE9B",
      "#FAE042",
      "#EFBB35",
      "#DFA612"
    ];

    setColor(colors[Math.floor(Math.random() * colors.length)]);
  }

  return (
    <button onClick={onClick} style={{ backgroundColor: color }}>
      Click to Change Button Color
    </button>
  );
}

const container = document.createElement("div");
document.body.appendChild(container);
render(<StatefulFn />, container);

Phương thức useState rất được thiết kế để được sử dụng với một giá trị duy nhất và không phải là một đối tượng trạng thái theo cách hoạt động của các thành phần lớp. Do đó, ta phải tự mình duy trì một đối tượng trạng thái theo cách thủ công hoặc đơn giản hơn, chỉ cần gọi useState nhiều lần để theo dõi từng biến trong trạng thái của ta :

const [color, setColor] = useState(false);
const [size, setSize] = useState('medium');
const [reptile, setReptile] = useState('alligator');


Vòng đời thành phần

Một lỗi khác của việc sử dụng các thành phần chức năng là thiếu các phương pháp vòng đời của chúng. Một phần khác của tính năng Hooks là việc bổ sung useEffect là sự kết hợp của componentDidMount , componentDidUpdatecomponentWillUnmount .

Nói một cách đơn giản hơn, useEffect sẽ kích hoạt sau lần hiển thị ban đầu và bất kỳ lần hiển thị nào tiếp theo.

Nếu bạn đã quen thuộc với vòng đời của thành phần lớp React, bạn biết rằng việc đặt mã với các tác dụng phụ trong phương thức kết xuất của bạn là rất tệ. Đó là lý do tại sao các phương pháp vòng đời tồn tại để bắt đầu.

Một tác dụng phụ như vậy là kích hoạt một yêu cầu mạng và sau đó cập nhật trạng thái với một giá trị được trả về. Trong ví dụ tiếp theo, tôi sẽ mô phỏng một kết nối mạng rất chậm bằng cách sử dụng setTimeout và sẽ hiển thị thông báo đang tải trong khi ta chờ đợi:

import React, { useEffect, useState } from "react";
import { render } from "react-dom";

function EffectedFn() {
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    setTimeout(() => {
      setLoading(false);
    }, 1000 * 10);
  });

  return (
    <div>
      {loading && <span>Loading...</span>}
      {!loading && <span>All Done!</span>}
    </div>
  );
}

const container = document.createElement("div");
document.body.appendChild(container);
render(<EffectedFn />, container);

Một điều thú vị khi sử useEffect là nó không chặn trình duyệt cập nhật màn hình như cách componentDidMountcomponentDidUpdate làm. Điều này giúp đảm bảo mọi thứ có vẻ đáp ứng và linh hoạt cho user của bạn!

Để giúp cải thiện hiệu suất hơn nữa, đặc biệt là khi làm việc với nhiều biến trạng thái, bạn có thể useEffect chỉ kích hoạt khi một giá trị nhất định đã thay đổi:

useEffect(() => {
  setTimeout(() => {
    setLoading(false);
  }, 1000 * 10);
}, [loading]);

Nhưng tôi không muốn sử dụng Hooks!

Điều thực sự tuyệt vời về Hooks là bạn không cần phải sử dụng chúng nếu không muốn. Nếu bạn quan tâm đến việc sử dụng các lớp học, bạn có thể tiếp tục chạy xe tải. Nếu bạn lo sợ rằng bạn cần phải cập nhật tất cả các chức năng hiện có, không bị móc nối của bạn , đừng như vậy.

Hooks tương thích ngược 100% nên không cần phải cố gắng cập nhật bất kỳ mã hiện có nào. Các lớp học sẽ không đi đến đâu và nếu / khi đã sẵn sàng bắt đầu sử dụng Hooks, miễn là bạn đang sử dụng version React hỗ trợ nó, bạn có thể làm như vậy.

Kết luận

Cá nhân tôi chán và mệt mỏi với việc chuyển các chức năng thành các lớp khi tôi cần hỗ trợ trạng thái và vòng đời, vì vậy đối với tôi, Hooks là một bổ sung rất đáng hoan nghênh.

Ngoài ra, thật dễ dàng để tạo hook của bạn hoặc sử dụng hook được phát triển bởi cộng đồng React lớn hơn. Đã có bộ sưu tập các móc có sẵn đang bật lên từ tráiphải .

Nếu bạn giống tôi và đã sẵn sàng bắt đầu sử dụng Hooks ngay hôm nay và muốn xem mã từ bài viết này trong thực tế, hãy truy cập CodeSandbox .


Tags:

Các tin liên quan