Giới thiệu
React cung cấp cho chúng ta hai hook quan trọng là useState và useRef để lưu trữ giá trị qua các lần render. Tuy nhiên, chúng hoạt động khác nhau và được sử dụng cho các tình huống khác nhau. Trong bài viết này, chúng ta sẽ phân tích rõ ràng khi nào nên sử dụng useState và khi nào nên sử dụng useRef để tối ưu hóa hiệu suất và trải nghiệm người dùng trong ứng dụng React của bạn.
1. useState
Tổng quan
useState là một hook dùng để lưu trữ dữ liệu có ảnh hưởng đến việc render của component. Khi giá trị của state thay đổi, component sẽ được re-render, giúp UI hiển thị giá trị mới.
Cách sử dụng
Dưới đây là một ví dụ đơn giản về cách sử dụng useState:
javascript
function Counter() {
const [count, setCount] = useState(0); // 🔄 triggers re-render
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
);
}
Mỗi lần nhấn nút, giá trị count sẽ được cập nhật và React sẽ re-render UI để hiển thị giá trị mới.
Thực hành tốt nhất
- Chỉ sử dụng
useStatecho dữ liệu cần hiển thị trong UI. - Tránh sử dụng
useStatecho các giá trị không ảnh hưởng đến giao diện.
2. useRef
Tổng quan
useRef là một hook lưu trữ giá trị có thể thay đổi mà không gây ra re-render cho component. Điều này rất hữu ích khi bạn cần lưu trữ tham chiếu đến các DOM node hoặc các giá trị không ảnh hưởng đến UI.
Cách sử dụng
Dưới đây là một ví dụ về cách sử dụng useRef:
javascript
function Timer() {
const intervalRef = useRef<number | null>(null); // 🗃️ stable across renders
function start() {
intervalRef.current = window.setInterval(() => {
console.log("tick");
}, 1000);
}
function stop() {
if (intervalRef.current) clearInterval(intervalRef.current);
}
return (
<>
<button onClick={start}>Start</button>
<button onClick={stop}>Stop</button>
</>
);
}
Trong ví dụ này, intervalRef giữ ID của timer nhưng không gây ra re-render cho component.
Thực hành tốt nhất
- Sử dụng
useRefđể lưu trữ các giá trị không cần re-render. - Tránh sử dụng
useRefcho các giá trị cần hiển thị trong UI.
3. Khi nào sử dụng cái nào?
Sử dụng useState khi:
- Giá trị ảnh hưởng đến việc render.
- UI cần cập nhật khi giá trị thay đổi.
- Ví dụ: bộ đếm, trường nhập liệu, chuyển đổi giao diện, dữ liệu được lấy về.
Sử dụng useRef khi:
- Giá trị cần tồn tại qua các lần render nhưng không ảnh hưởng đến UI.
- Bạn muốn tránh các re-render không cần thiết.
- Ví dụ:
- Truy cập các phần tử DOM (
ref={myRef}) - Lưu trữ ID của timer, kết nối WebSocket
- Giữ giá trị trước đó để so sánh
- Truy cập các phần tử DOM (
4. Ví dụ: Sử dụng cả hai cùng nhau
javascript
function InputFocus() {
const [text, setText] = useState(""); // shows in UI
const inputRef = useRef<HTMLInputElement>(null); // reference to DOM
return (
<>
<input ref={inputRef} value={text} onChange={e => setText(e.target.value)} />
<button onClick={() => inputRef.current?.focus()}>
Focus input
</button>
</>
);
}
Trong ví dụ này:
useStatelưu trữ văn bản (gây ra render).useReflưu trữ tham chiếu DOM (không cần render).
5. Mô hình tư duy nhanh 🧠
- useState = cho UI → thay đổi → re-render.
- useRef = cho lưu trữ → thay đổi → không re-render.
6. Bảng tóm tắt
| Tính năng | useState ✅ |
useRef ✅ |
|---|---|---|
| Gây ra re-render khi thay đổi | ✔️ Có | ❌ Không |
| Tốt nhất cho | Giá trị UI (văn bản, đếm, chuyển đổi) | Tham chiếu DOM, timer, lưu trữ |
| Tồn tại qua các lần render | ✔️ Có | ✔️ Có |
| Có thể thay đổi mà không gây render | ❌ Không | ✔️ Có |
| Sử dụng phổ biến | Trường nhập, bộ đếm, dữ liệu lấy về | Tập trung vào input, lưu ID, giá trị trước, tham chiếu WebSocket |
Kết luận
Bây giờ bạn đã hiểu rõ khi nào nên sử dụng useState và khi nào nên sử dụng useRef trong React. Hãy áp dụng những kiến thức này vào dự án của bạn để tối ưu hóa hiệu suất và trải nghiệm người dùng. Nếu bạn có bất kỳ câu hỏi nào, đừng ngần ngại để lại ý kiến dưới bài viết này!
Câu hỏi thường gặp (FAQ)
1. useState có thể được sử dụng trong các component không?
Có, useState có thể được sử dụng trong bất kỳ component nào của React.
2. Tôi có thể sử dụng cả hai hook cùng một lúc không?
Có, bạn hoàn toàn có thể sử dụng cả useState và useRef trong cùng một component để tận dụng lợi thế của cả hai.
3. Có bao giờ tôi nên sử dụng useRef thay cho useState không?
Nếu giá trị bạn đang lưu trữ không ảnh hưởng đến UI, bạn nên sử dụng useRef để tránh các re-render không cần thiết.