Ngừng Lặp Lại: Cách Custom Hooks Biến Đổi Mã React Của Bạn
Giới thiệu
Bạn có bao giờ sao chép và dán cùng một đoạn mã giữa hai component khác nhau trong React chưa?
Có thể đó là đoạn mã để:
- Lấy dữ liệu từ API.
- Quản lý giá trị nhập của form.
- Lắng nghe các phím bấm.
- Kết nối với websocket.
Nếu có, chắc hẳn bạn đã cảm thấy sự phiền phức. Nó hoạt động nhưng rất lộn xộn. Và nếu bạn phát hiện lỗi trong đoạn mã đó, bạn phải nhớ sửa ở mọi nơi mà bạn đã dán nó. Thật khó chịu.
Vậy nếu có một cách để viết logic đó một lần và sử dụng nó ở mọi nơi thì sao? Có đó. Đó chính là Custom Hook.
Custom Hook Là Gì? (Không Giới Thiệu Lằng Nhằng)
Hãy tưởng tượng bạn có một công cụ điện yêu thích, như một cái khoan. Bạn không xây dựng một cái khoan mới từ đầu mỗi khi bạn cần lắp đặt một cái kệ. Bạn chỉ cần lấy cái khoan từ hộp công cụ và sử dụng nó.
Custom Hook giống như công cụ điện cá nhân của bạn cho React. Nó không phải là một tính năng mới của React mà bạn phải cài đặt. Nó chỉ là một hàm JavaScript có tên bắt đầu bằng "use" và có thể sử dụng các hook khác bên trong.
Thế là xong. Bạn chỉ đang tạo ra một hàm.
Xây Dựng Một Công Cụ: useLocalStorage
Một nhu cầu rất phổ biến là lưu trữ một thứ gì đó vào trình duyệt của người dùng (như tên người dùng) để nó không bị mất khi họ làm mới trang.
Cách Lộn Xộn (Không Sử Dụng Custom Hook)
Bạn sẽ sao chép cùng một đoạn mã useState và useEffect vào mỗi component cần nó:
javascript
// Trong ComponentOne.js và ComponentTwo.js
function MyComponent() {
const [name, setName] = useState(() => {
// Lấy tên đã lưu từ trình duyệt khi component bắt đầu
const savedName = localStorage.getItem('name');
return savedName ? JSON.parse(savedName) : '';
});
useEffect(() => {
// Lưu tên vào trình duyệt mỗi khi nó thay đổi
localStorage.setItem('name', JSON.stringify(name));
}, [name]);
return <input value={name} onChange={e => setName(e.target.value)} />;
}
Cách Sạch Sẽ (Sử Dụng Custom Hook)
Hãy cùng xây dựng công cụ useLocalStorage:
Bước 1: Tạo một tệp mới: useLocalStorage.js
Bước 2: Xây dựng công cụ của bạn bên trong nó:
javascript
// useLocalStorage.js
import { useState, useEffect } from 'react';
function useLocalStorage(key, initialValue) {
const [value, setValue] = useState(() => {
// Lấy giá trị đã lưu từ trình duyệt khi hook bắt đầu
const savedValue = localStorage.getItem(key);
return savedValue ? JSON.parse(savedValue) : initialValue;
});
useEffect(() => {
// Lưu giá trị vào trình duyệt mỗi khi nó thay đổi
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue];
}
export default useLocalStorage;
Bước 3: Bây giờ, hãy sử dụng công cụ mạnh mẽ mới của bạn ở bất kỳ đâu!
javascript
// Trong AnyComponent.js
import useLocalStorage from './useLocalStorage';
function AnyComponent() {
const [name, setName] = useLocalStorage('name', '');
return <input value={name} onChange={e => setName(e.target.value)} />;
}
Điều Gì Đã Xảy Ra?
Chúng ta đã viết logic một lần: Tất cả mã lộn xộn liên quan đến localStorage giờ chỉ nằm trong một nơi.
- Chúng ta đã làm cho nó có thể tái sử dụng: Bất kỳ component nào trong ứng dụng của chúng ta giờ đây đều có thể sử dụng hook useLocalStorage này.
- Chúng ta đã làm cho nó dễ dàng sửa chữa: Nếu chúng ta phát hiện lỗi, chỉ cần sửa trong một tệp (useLocalStorage.js), và nó sẽ tự động được sửa trong mọi component sử dụng nó.
Cách Bắt Đầu
- Tìm kiếm sự lặp lại: Lần tới khi bạn sắp sao chép mã từ một component sang component khác... DỪNG LẠI.
- Tạo một tệp mới: Đặt tên cho nó là use[YourFeature].js (ví dụ: useApi.js, useToggle.js).
- Di chuyển mã lặp lại vào hàm đó.
- Trả về các giá trị mà component của bạn cần (thường là một giá trị và một hàm setter, giống như useState).
Nhập và sử dụng nó trong các component của bạn. Cảm thấy như một phù thủy.
Custom Hooks không phải là về việc trở thành một thiên tài React. Chúng là về việc lười biếng theo cách thông minh nhất có thể: viết ít mã hơn và làm cho cuộc sống của bạn dễ dàng hơn.
Thực Hành Tốt Nhất
- Tái sử dụng mã: Sử dụng Custom Hook để giảm thiểu sự lặp lại trong mã.
- Tên rõ ràng: Đặt tên cho Custom Hook sao cho dễ hiểu và liên quan đến chức năng của nó.
Những Cái Bẫy Thường Gặp
- Quên khai báo hook: Hãy chắc chắn rằng bạn luôn bắt đầu tên hàm bằng "use".
- Sử dụng không đúng ngữ cảnh: Custom Hooks cần được sử dụng trong các component function.
Mẹo Tối Ưu Hiệu Suất
- Giảm số lượng state: Tránh sử dụng quá nhiều state trong một component để tăng hiệu suất.
- Thực hiện kiểm tra nhẹ nhàng: Kiểm tra xem giá trị đã thay đổi trước khi thực hiện các tác vụ như lưu trữ.
Giải Quyết Vấn Đề
Nếu bạn gặp sự cố với Custom Hook của mình:
- Kiểm tra console: Xem có bất kỳ thông báo lỗi nào không.
- Đảm bảo trả về đúng giá trị: Kiểm tra xem Custom Hook trả về giá trị mà bạn mong đợi.
Câu Hỏi Thường Gặp
- Custom Hook có thể sử dụng trong class component không?
- Không, Custom Hook chỉ có thể sử dụng trong function component.
- Tôi có thể tạo nhiều Custom Hook không?
- Có, bạn có thể tạo bao nhiêu tùy ý.
Kết Luận
Custom Hooks giúp bạn tổ chức mã tốt hơn và giảm thiểu sự lặp lại. Hãy bắt đầu sử dụng chúng để biến mã React của bạn trở nên gọn gàng và dễ bảo trì hơn. Bạn sẽ chuyển đổi điều gì thành một Custom Hook đầu tiên? Chia sẻ ý tưởng của bạn bên dưới!
Nếu bạn muốn ủng hộ nội dung của tôi, bạn có thể mua cho tôi một ly cà phê tại đây: Mua cho tôi một ly cà phê