useState Quá tải? Cách useReducer giúp quản lý State dễ dàng hơn trong React

0 0 0

Người đăng: Vũ Tuấn

Theo Viblo Asia

Nếu bạn đã xây dựng ứng dụng React một thời gian, chắc hẳn bạn thường xuyên sử dụng useState để quản lý state. Nó đơn giản, trực quan và hoạt động tốt trong những trường hợp cơ bản. Nhưng khi logic state của component trở nên phức tạp, việc sử dụng nhiều useState, các cập nhật chồng chéo và các hàm xử lý rối rắm có thể biến mã nguồn của bạn thành một mớ hỗn độn.

Đây chính là lúc useReducer phát huy tác dụng — một giải pháp thay thế dễ mở rộng và bảo trì hơn để quản lý state phức tạp. Trong bài viết này, chúng ta sẽ tìm hiểu khi nào và tại sao bạn nên chuyển từ useState sang useReducer.

1. Khi nào useState gặp vấn đề?

✅ useState hoạt động tốt khi:

  • Các giá trị state đơn giản và độc lập (ví dụ: isLoading, inputValue).
  • Cập nhật trạng thái đơn giản (setCount(count + 1)).

❌ Nhưng nó không hiệu quả khi:

  • Các cập nhật state phụ thuộc lẫn nhau.
  • Cần xử lý logic chuyển đổi state phức tạp.
  • State trở nên lồng nhau quá sâu hoặc có sự liên kết phức tạp.

VD về trường hợp useState gặp trục trặc:

const [form, setForm] = useState({ username: '', email: '', password: '', errors: {}, isSubmitting: false,
}); const handleSubmit = async () => { setForm(prev => ({ ...prev, isSubmitting: true })); try { const response = await submitForm(form); setForm(prev => ({ ...prev, success: true, errors: {} })); } catch (error) { setForm(prev => ({ ...prev, errors: error.response.data })); } finally { setForm(prev => ({ ...prev, isSubmitting: false })); }
};

Việc này sẽ nhanh chóng trở nên lộn xộn — hãy tưởng tượng đến việc thêm xác thực, logic đặt lại hoặc nhiều trường hơn!

2. Cách useReducer giải quyết vấn đề

Lấy cảm hứng từ Redux nhưng đơn giản hơn rất nhiều, useReducer tập trung logic state vào một hàm reducer, giúp việc cập nhật state trở nên rõ ràng và dễ debug hơn.

Cấu trúc cơ bản của useReducer:

const [state, dispatch] = useReducer(reducer, initialState);

Tái cấu trúc biểu mẫu bằng useReducer

Thay vì lan truyền và cập nhật trạng thái theo cách thủ công, chúng ta có thể xử lý các thay đổi trạng thái hiệu quả hơn:

const initialState = { username: '', email: '', password: '', errors: {}, isSubmitting: false, success: false,
}; function formReducer(state, action) { switch (action.type) { case 'FIELD_CHANGE': return { ...state, [action.field]: action.value }; case 'SUBMIT_START': return { ...state, isSubmitting: true, errors: {} }; case 'SUBMIT_SUCCESS': return { ...state, isSubmitting: false, success: true }; case 'SUBMIT_FAILURE': return { ...state, isSubmitting: false, errors: action.errors }; case 'RESET_FORM': return initialState; default: return state; }
} // Usage in component
const [state, dispatch] = useReducer(formReducer, initialState); const handleSubmit = async () => { dispatch({ type: 'SUBMIT_START' }); try { await submitForm(state); dispatch({ type: 'SUBMIT_SUCCESS' }); } catch (error) { dispatch({ type: 'SUBMIT_FAILURE', errors: error.response.data }); }
};

Lợi ích của useReducer:

  • Phân tách rõ ràng logic state.
  • Dễ debug hơn (các thay đổi state đều rõ ràng và có thể ghi log).
  • Dễ mở rộng và quản lý state phức tạp hơn.

3. Khi nào nên sử dụng useReducer?

Không phải mọi component đều cần useReducer. Dưới đây là những trường hợp mà nó thực sự hữu ích:

  • Biểu mẫu có nhiều trường và cần validation.
  • Quản lý state theo quy trình (ví dụ: tải dữ liệu → thành công → lỗi).
  • Component có logic phức tạp với nhiều state liên quan.
  • Cần tối ưu hiệu suất (giảm số lần re-render so với việc dùng nhiều useState).

4. Những hiểu lầm thường gặp về useReducer

🚫 "Nó quá phức tạp cho dự án nhỏ."

→ Thực ra nó chỉ là một hàm! Nếu logic state của bạn đang rối, hãy cân nhắc sử dụng nó.

🚫 "Chỉ dùng cho state toàn cục."

→ Không đúng! useReducer hoàn toàn phù hợp để quản lý state cục bộ trong component.

🚫 "Nếu dùng useReducer thì cần Redux."

→ Sai! useReducer là một hook độc lập, không cần đến Redux hay thư viện nào khác.

5. Kết luận: Có nên ngừng sử dụng useState?

Không — useState vẫn rất hữu ích cho những trường hợp đơn giản. Nhưng nếu bạn đang gặp phải những vấn đề sau:

  • Viết quá nhiều setState trong một hàm.
  • Gặp khó khăn khi cập nhật state lồng nhau.
  • Cần debug chi tiết các thay đổi state.

…thì đã đến lúc thử useReducer. Điều này sẽ giúp code của bạn rõ ràng, dễ bảo trì hơn và đồng nghiệp của bạn sẽ cảm ơn bạn về điều đó!

Bình luận

Bài viết tương tự

- vừa được xem lúc

Tìm hiểu về Redux Thunk

Chào mọi người, nếu bạn là người đã biết về React và đang làm quen với Redux chắc hẳn bạn đang rất mơ hồ về các khái niệm cơ bản của Redux như dispatch, store, action creator,... bạn còn đang vật lộn với đống document của Redux để hiểu những khái niệm đó và bạn nghe ai đó trong team nói về Redux Thu

0 0 401

- vừa được xem lúc

[React] Giới thiệu tổng quát về Redux Toolkit

1. Redux Toolkit (RTK) là gì và tại sao lại có nó. . .

0 0 6.6k

- vừa được xem lúc

Uống Pepsi code Vue đi - Uống Cocacola code React nha ;)

. (Nguồn ảnh: Internet). Chào các bạn, chào các bạn. Let's go . 1.

0 0 149

- vừa được xem lúc

Cài đặt taillwind css cho dự án React

Trong bài viết cùng mình tìm hiểu cách cài đặt tailwind css cho một dự án React sẵn có. .

0 0 148

- vừa được xem lúc

Formik vs React Hook Form (Phần 1)

Các lập trình viên Front End đều làm việc rất nhiều với form cùng sự phức tạp của ứng dụng. Do vậy chúng ta cần những thư viện form mạnh mẽ hỗ trợ quản lý các form state, form validation... Thành phần module. Formik bao gồm có 9 dependencies khác. . React Hook Form thì không có.

0 0 373

- vừa được xem lúc

Hướng dẫn React Redux cho người mới bắt đầu - Phần 1

Lời mởi đầu. Chào các bạn, ở thời điểm thực hiện bài viết này mình cũng là một người đang bắt đầu tìm hiểu và học với ReactJs và Redux, trong quá trình tìm hiểu đọc các tài liệu về thư viện này mình có tìm được một bài hướng dẫn khá hay nên đã quyết định chia sẻ với mọi người .

0 0 283