Introducing Hooks

Hooks là một phần bổ sung mới trong React 16.8. Hooks giúp bạn sử dụng state và các tính năng khác của React mà không cần phải viết class.

import React, { useState } from 'react';

function Example() {
  // Declare a new state variable, which we'll call "count"  const [count, setCount] = useState(0);
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

Function mới useState là “Hook”"đầu tiên chúng ta sẽ học, nhưng ví dụ này chỉ là mở đầu. Đừng lo nếu như bạn chưa hiểu.

Bạn có thể bắt đầu học về Hooks ở phần tiếp theo. Trong phần này, chúng ta sẽ tiếp tục giải thích tại sao chúng tôi thêm Hooks vào React và cách mà Hook có thể giúp bạn viết các ứng dụng tuyệt vời.

Note:
React 16.8 là phiên bản đầu tiên được giới thiệu có hỗ trợ Hooks. Khi cập nhật, bạn đừng quên cập nhật tất cả các packages, kể cả ReactDOM. React Native hỗ trợ Hooks từ bản 0.59 của React Native.

Không có thay đổi đột phá
Trước khi chúng ta tiếp tục, chú ý rằng Hooks là:

  • Hoàn toàn là tự chọn. Bạn có thể thử dùng trong một vài component mà không cần phải viết lại code đã có. Nhưng bạn có thể không cần học hoặc sử dụng Hooks ngay bây giờ nếu bạn không muốn.
  • 100% tương thích với phiên bản cũ Hook không chứa các thay đổi lớn.
  • Có sẵn hiện tại Hooks đã có thể sử dụng với bản v16.8.0.

Không hề có kế hoạch loại bỏ classes từ React. Bạn có thể đọc thêm về chiến lược áp dụng dân dần cho Hooks trong phần cuối của bài này.

Hooks không thay thế kiến thức của bạn về các khái niệm của React. Thay vào đó, Hooks cung cấp thêm các API trực tiếp đến các khái niệm của React mà bạn đã biết: props, state, context, refs, và lifecycle. Như chúng ta sẽ giới thiệu, Hooks cũng cung cấp một cách mới đầy mạnh mẽ để kết hợp chúng.

Nếu bạn chỉ muốn bắt đầu học Hooks, hãy thoải mái tiến đến phần tiếp theo. Bạn cũng có thể tiếp tục đọc phần này để biết thêm tại sao chúng tôi bổ sung Hooks, và cách chúng ta bắt đầu sử dụng chúng mà không cần viết lại các ứng dụng của chúng ta.

Động lực
Hooks giải quyết nhiều loại của các vấn đề dường như không liên quan trong React mà chúng ta đã gặp hơn 5 năm của việc viết và bảo trì hàng chục nghìn component. Liệu khi bạn đang học React, sử dụng nó hàng ngày, hoặc thậm chí thích một thư viện khác với cùng mô hình thành phần, bạn có thể nhận ra một vài vấn đề đó.

Khó tái sử dụng stateful logic giữa các component
React không cung cấp cách để “gắn” hành vi có thể tái sử dụng cho component (ví dụ như kết nối nó đến nơi lưu trữ). Nếu như bạn phải làm việc với React trong một thời gian, bạn có thể quen với các mô hình như render propshigher-order components để thử giải quyết chúng. Nhưng các mô hình này yêu cầu tái cấu trúc các component của bạn khi bạn sử dụng, điều có thể trở nên cản trở và làm code khó để theo dõi. Nếu bạn nhìn vào ứng dụng điển hình của React trong ReactDevTools, bạn sẽ dễ thấy “wrapper hell” của các component bọc bởi các lớp của người cung cấp, khách hàng, các higher-order component, render props và các abstraction khác. Khi chúng ta có thể lọc chúng ra từ DevTools, điều này chỉ ra những vấn đề sâu hơn: React cần nguồn gốc tốt hơn cho việc chia sẻ stateful logic.

Với Hooks, bạn có thể tách stateful logic từmột component nên nó có thể được kiểm tra một cách độc lập và được tái sử dụng. Hooks cho phép bạn tái sử dụng stateful logic mà không cần thay đổi hệ thống component của bạn. Điều này làm nó dễ chia sẻ Hooks giữa các component hoặc với cộng đồng.

Các component phức tạp trở nên khó hiểu

Chúng tôi thường phải bảo trì các component khi bắt đầu rất đơn giản nhưng phát triển thành đống hỗn độn không thể kiểm soát của stateful logic và side effects. Mỗi phương thức lifecycle thường chứa hỗn hợp của logic không liên quan. Ví dụ, các component có thể thực hiện nạp dữ liệu trong componentDidMount và componentDidUpdate. Tuy nhiên, phương thức componentDidMount có thể cũng chứa vài logic không liên quan mà cài đặt các event listener, với dọn dẹp được thực hiện trong componentWillMount. Code liên quan lẫn nhau thay đổi cùng nhau bị tách ra các phần, nhưng code hoàn toàn không liên quan lại kết thúc được gộp lại trong một phương thức. Điều này quá dễ để giới thiệu lỗi và sự không nhất quán.

Trong rất nhiều trường hợp nó không khả thi để tách các component thành các component nhỏ hơn bởi vì stateful logic ở khắp nơi. Điều này cũng là rất khó để kiểm tra chúng. Đây là một trong các lý do nhiều người thích kết hợp React với thư viện quản lý state riêng biệt.
Tuy nhiên, điều này thường đưa ra quá nhiều sự trừu tượng, yêu cầu bạn phải nhảy vào giữa nhiều file khác nhau, và làm các component đang tái sử dụng trở nên khó hơn.

Để giải quyết điều này, Hooks giúp bạn tách một component thành các hàm nhỏ hơn dựa trên những mảnh có liên quan (như là cài đặt một đăng ký hay lấy dữ liệu), thay vì tập trung vào tách dựa trên các phương thức lifecycle. Bạn có thể chọn quản lý local state của component với reducer để dễ dự đoán hơn.

Các class làm cả con người và máy móc bối rối
Trong phần thêm để làm code tái sử dụng và tổ chức code khó hơn, chúng tôi tìm ra rằng các class có thể trở thành cản trở lớn để học React. Bạn phải hiểu cách hoạt động trong JavaScript, điều mà rất khác so với cách hoạt động trong hầu hết các ngôn ngữ khác. Bạn phải nhớ để gán các event handler. Không có đề xuất cú pháp không ổn định, code sẽ rất dài dòng. Mọi người có thể hiểu props,state, và luồng dữ liệu top-down tốt một cách tuyệt vời nhưng vẫn vất vả với các class. Sự khác biệt giữa function và class component trong React và khi nào sử dụng đều dẫn đến sự bất đồng ngay cả giữa những React developer kinh nghiệm.

Ngoài ra, React đã được phát triển khoảng 5 năm, và chúng tôi muốn chắc rằng React thích hợp trong 5 năm nữa. Như Svelte, Angular, Glimmer, và những người khác, biên soạn trước các component rất có tiềm năng trong tương lai. Đặc biệt là nếu nó không giới hạn các mẫu. Gần đây, chúng tối đã được trải nghiệm đóng gói component với Prepack, và chúng tôi đã thấy kết quả đầy hứa hẹn. Tuy nhiên, chúng tôi tìm ra các class component có thể tạo ra phần vô ý có thể làm những tối ưu trở về con đường chậm hơn. Các class cũng thể hiện lỗi với các tools của hiện tại. Ví dụ, các class giảm thiểu không được tốt và chúng làm hot reloading không ổn định và thiếu tin cậy. Chúng tôi muốn đưa ra một API làm nó có nhiều khả năng cho code giữ ổn định.

Để giải quyết vấn đề đó, Hooks giúp bạn sử dụng nhiều tính năng của React mà không sử dụng các class. Về mặt khái niệm, các component của React luôn gần gũi với function hơn. Hooks bao trọn các function, nhưng không cần hi sinh tinh thần của React. Hooks cung cấp quyền truy cập vào cửa thoát hiểm và không yêu cầu bạn học nhưng chức năng phức tạp hay tương tác với các kĩ thuật lập trình.

Chiến lược áp dụng dần dần

Chúng tôi biết các React developer tập trung vào đưa ra các sản phẩm và không có thời gian tìm hiểu vào các API mới được phát hành.
Hooks rất mới, và sẽ tốt hơn nếu đợi các ví dụ và hướng dẫn trước khi xem xét học hay áp dụng chúng.

Chúng tôi cũng hiểu rằng thêm một điều mới vào React là rất khó khăn. Cho những người đọc tò mò, chúng tôi đã chuẩn bị một RFC chi tiết đào sâu vào động lực với nhiều chi tiết, và cung cấp các quan điểm bổ sung về các quyết định thiết kế cụ thể và nghệ thuật liên quan.

Quan trọng là, Hooks hoạt động side-by-side với code đã có nên bạn có thể áp dụng chúng một cách từ từ. Không có điều gì phải vội chuyển qua Hooks. Chúng tôi khuyên bạn tránh các “big rewrites”, đặc biệt là các class component phức tạp hiện có. Điều này tốn một ít suy nghĩ để bắt đầu “thinking in Hooks”. Với kinh nghiệm của chúng tôi, tốt nhất là bắt đầu luyện tập sử dụng Hooks với các component mới chưa quan trọng, và đảm bảo rằng mọi người trong nhóm của bạn cảm thấy thoải mái với chúng. Sau khi bạn thử dùng Hooks, mong bạn hãy thoải mái gửi phản hồi cho chúng tôi, tích cực hoặc tiêu cực.

Chúng tôi chú định cho Hooks bao quát mọi trường hợp cho classes, nhưng chúng tôi sẽ tiếp tục hỗ trợ các class component trong tương lai gần. Ở FaceBook, chúng tôi có hàng chục nghìn component được biết như class, và chúng tôi hoàn toàn không có ý định viết lại chúng. Thay vào đó, chúng tôi đang bắt đầu sử dụng Hooks trong code mới đồng hành cùng class.