Hooks Nâng Cao trong React: useContext, useReducer, useMemo, useCallback

Tạo bởi Hoàng Vũ, chỉnh sửa cuối lúc 28 tháng 1, 2025

React cung cấp các Hooks nâng cao để giải quyết các vấn đề phức tạp hơn khi xây dựng ứng dụng. Trong bài viết này, chúng ta sẽ tìm hiểu về 4 hooks nâng cao: useContext, useReducer, useMemo, và useCallback.

1. useContext

useContext giúp bạn truy cập dữ liệu từ Context API mà không cần phải sử dụng các props trung gian.

Khi nào dùng useContext?

  • Khi cần quản lý state toàn cục hoặc chia sẻ dữ liệu giữa nhiều components.
  • Ví dụ: thông tin người dùng, chủ đề giao diện, hoặc ngôn ngữ.

Ví dụ:

import React, { createContext, useContext } from "react";		

// Tạo một Context		
const ThemeContext = createContext();		
			
function ThemeProvider({ children }) {		
	  const theme = "dark";		
	  return (		
	    <ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>		
	  );		
}		
			
function DisplayTheme() {		
	  const theme = useContext(ThemeContext);		
	  return <div>Current theme: {theme}</div>;		
}		
			
export default function App() {		
	  return (		
	    <ThemeProvider>		
	      <DisplayTheme />		
	    </ThemeProvider>		
	  );		
}		

2. useReducer

useReducer là một hook thay thế mạnh mẽ cho useState khi cần quản lý state phức tạp hoặc có nhiều hành động khác nhau.

Khi nào dùng useReducer?

  • Khi state có logic cập nhật phức tạp (nhiều nhánh hoặc phụ thuộc vào hành động cụ thể).
  • Khi cần sự rõ ràng và dễ bảo trì trong quản lý state.

Ví dụ:

import React, { useReducer } from "react";		
			
const initialState = { count: 0 };		
			
	function reducer(state, action) {		
	  switch (action.type) {		
	    case "increment":		
	      return { count: state.count + 1 };		
	    case "decrement":		
	      return { count: state.count - 1 };		
	    default:		
	      return state;		
	  }		
}		
			
export default function Counter() {		
	  const [state, dispatch] = useReducer(reducer, initialState);		
			
	  return (		
	    <div>		
	      <p>Count: {state.count}</p>		
	      <button onClick={() => dispatch({ type: "increment" })}>+</button>		
	      <button onClick={() => dispatch({ type: "decrement" })}>-</button>		
	    </div>		
	  );		
}		

3. useMemo

useMemo giúp tối ưu hiệu suất bằng cách ghi nhớ kết quả của một phép tính và chỉ thực hiện lại khi các phụ thuộc thay đổi.

Khi nào dùng useMemo?

  • Khi có một phép tính tốn kém và muốn tránh thực hiện lại nếu không cần thiết.
  • Khi cần ghi nhớ giá trị giữa các lần render.

Ví dụ:

import React, { useMemo, useState } from "react";		
			
function ExpensiveCalculation(num) {		
	  console.log("Calculating...");		
	  return num * 2;		
}		
			
export default function App() {		
	  const [count, setCount] = useState(0);		
	  const [otherState, setOtherState] = useState(0);		
			
	  const result = useMemo(() => ExpensiveCalculation(count), [count]);		
			
	  return (		
	    <div>		
	      <p>Result: {result}</p>		
	      <button onClick={() => setCount(count + 1)}>Increase Count</button>		
	      <button onClick={() => setOtherState(otherState + 1)}>Change Other State</button>		
	    </div>		
	  );		
}		
			

4. useCallback

useCallback giúp tối ưu hiệu suất bằng cách ghi nhớ một hàm giữa các lần render. Nó rất hữu ích khi truyền các hàm vào components con để tránh render lại không cần thiết.

Khi nào dùng useCallback?

  • Khi truyền một hàm callback xuống components con qua props.
  • Khi muốn tối ưu hóa với React.memo.

Ví dụ:

import React, { useCallback, useState } from "react";		
			
function Child({ onClick }) {		
	  console.log("Child rendered");		
	  return <button onClick={onClick}>Click Me</button>;		
}		
			
const MemoizedChild = React.memo(Child);		
			
export default function App() {		
	  const [count, setCount] = useState(0);		
			
	  const handleClick = useCallback(() => {		
	    console.log("Button clicked!");		
	  }, []);		
			
	  return (		
	    <div>		
	      <p>Count: {count}</p>		
	      <button onClick={() => setCount(count + 1)}>Increase Count</button>		
	      <MemoizedChild onClick={handleClick} />		
	    </div>		
	  );		
}		

Tóm tắt

Hook Mục đích chính Khi nào dùng?
useContext Truy cập dữ liệu từ Context API Khi cần chia sẻ state giữa nhiều components.
useReducer Quản lý state phức tạp với nhiều hành động Khi logic cập nhật state phức tạp.
useMemo Tối ưu hiệu suất bằng cách ghi nhớ kết quả tính toán Khi có phép tính tốn kém.
useCallback Tối ưu hiệu suất bằng cách ghi nhớ hàm callback Khi truyền hàm xuống components con.
Website Logo

Với hơn 10 năm kinh nghiệm lập trình web và từng làm việc với nhiều framework, ngôn ngữ như PHP, JavaScript, React, jQuery, CSS, HTML, CakePHP, Laravel..., tôi hy vọng những kiến thức được chia sẻ tại đây sẽ hữu ích và thiết thực cho các bạn.

Bình luận

Website Logo

Chào, tôi là Vũ. Đây là blog hướng dẫn lập trình của tôi.

Liên hệ công việc qua email dưới đây.

lhvuctu@gmail.com

Chúng Tôi Trên

Bạn đang muốn học về lập trình website?

Bạn cần nâng cao kiến thức chuyên nghiệp hơn để nâng cao cơ hội nghề nghiệp? Liên hệ