1. 17:43 11/10/2026
## Giới thiệu
Khi xây dựng các ứng dụng đa nền tảng bằng React, bạn thường thấy mình phải lặp lại logic tương tự trên web và di động. Việc duy trì hai phiên bản riêng biệt không chỉ lãng phí thời gian mà còn làm tăng nguy cơ sai lệch giữa các nền tảng. Giải pháp hiệu quả là tạo một thư viện custom hooks có thể tái sử dụng, được định nghĩa bằng TypeScript, giúp chia sẻ logic một cách an toàn giữa React Web và React Native.
## Tại sao sử dụng custom hooks?
- **Tái sử dụng code** – Một hook duy nhất có thể được nhập vào cả hai dự án, loại bỏ việc sao chép logic.
- **Tính nhất quán** – Thay đổi một lần ở nguồn sẽ ảnh hưởng đến tất cả người dùng, đảm bảo hành vi giống nhau trên web và di động.
- **Khả năng kiểm thử** – Hooks có thể được kiểm thử một cách độc lập mà không cần môi trường React thông qua các công cụ như React Testing Library hoặc Jest.
- **Type‑safety** – TypeScript cung cấp cho người dùng các tham số được đánh giá rõ ràng, giúp phát hiện lỗi sớm trong cả hai nền tảng.
## Thiết kế thư viện hooks
1. **Tách biệt các mối quan tâm** – Mỗi hook nên tập trung vào một chức năng duy nhất (ví dụ: quản lý trạng thái, xử lý tác vụ, định dạng dữ liệu).
2. **Sử dụng chung các kiểu** – Định nghĩa interface chung trong một gói @my‑hooks/shared để đảm bảo signature nhất quán.
3. **Tận dụng chế độ chạy của Node** – Sử dụng các câu lệnh điều kiện `import` dựa trên `process.env.PLATFORM` hoặc một plugin build để cung cấp các triển khai cụ thể cho từng nền tảng.
4. **Tích hợp CI** – Bao gồm các bước kiểm tra TypeScript và kiểm thử hooks trong quy trình CI/CD để đảm bảo các thay đổi không làm hỏng bất kỳ nền tảng nào.
## Thực hiện với TypeScript
```ts
// src/hooks/useDebounce.ts
import { useState, useEffect } from 'react';
export function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => setDebouncedValue(value), delay);
return () => clearTimeout(handler);
}, [value, delay]);
return debouncedValue;
}
```
Hook này hoạt động giống nhau trên web và di động vì nó chỉ sử dụng API useState và useEffect tiêu chuẩn của React.
**Thêm một hook chỉ dành cho nền tảng gốc**
```ts
// src/hooks/useBluetooth.ts (chỉ cho React Native)
import { useEffect, useState } from 'react';
import { BleManager } from 'react-native-ble-plx';
export function useBluetooth() {
const [devices, setDevices] = useState([]);
useEffect(() => {
const manager = new BleManager();
// triển khai quét thiết bị
}, []);
return { devices };
}
```
Bằng cách đặt tệp trong thư mục `native/` và sử dụng câu lệnh điều kiện import trong tệp chỉ mục, bạn có thể che giấu sự khác biệt này khỏi người dùng.
## Ví dụ thực tế
- **hooks/timer.ts** – Cung cấp các hàm `useCountdown`, `useStopwatch` để sử dụng trong cả bộ đếm thời gian trên web và tính năng đếm ngược trên màn hình khóa di động.
- **hooks/form.ts** – Bao gồm `useFormState` và `useAsyncValidation`, giúp đồng bộ hóa logic xác thực giữa các biểu mẫu web và di động.
- **hooks/network.ts** – Cung cấp `useFetch` với một lớp bao bọc xử lý các khác biệt về fetch của React Native so với browser.
## Lời khuyên
- **Đặt tên hook theo chức năng** – `use*` thể hiện rõ ràng rằng đây là hook.
- **Tận dụng các extension của IDE** – Sử dụng tính năng hoàn thành mã TypeScript để tự động kiểm tra các tham số bị thiếu.
- **Ghi lại các triển khai thay thế cho từng nền tảng** – Thêm ghi chú trong phần README về bất kỳ sự khác biệt nào giữa các nền tảng.
- **Kiểm thử cả hai môi trường** – Sử dụng các script test có điều kiện (ví dụ: `npm run test:web` và `npm run test:mobile`) để đảm bảo hooks hoạt động trên cả hai nền tảng.
## Kết luận
Bằng cách xây dựng một thư viện custom hooks được định nghĩa bằng TypeScript, bạn có thể đồng bộ hóa logic giữa React Web và React Native một cách hiệu quả, giảm trùng lặp code và cải thiện khả năng bảo trì. Một thiết kế rõ ràng, kết hợp kiểm thử nghiêm ngặt và quy trình CI/CD hiện đại, sẽ giúp bạn tận dụng tối đa phương pháp tiếp cận đa nền tảng này.