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

useState liệu có phải là “cây đũa thần” cho mọi bài toán React? Khám phá những lựa chọn thay thế hiệu quả

0 0 2

Người đăng: Thái Thịnh

Theo Viblo Asia

Khi mới bắt đầu với React, useState giống như câu thần chú giúp mọi thứ hoạt động trơn tru. Bạn muốn một nút theo dõi số lần nhấp? Hãy dùng useState. Bạn cần chuyển đổi trạng thái hiển thị của một modal? useState lại được gọi tên. Nhưng khi bạn đi sâu hơn vào thế giới phát triển React, bạn có thể bắt đầu tự hỏi: Liệu useState có phải là lựa chọn phù hợp cho mọi tình huống?

Câu trả lời, không có gì ngạc nhiên, đó là không. Mặc dù useState rất linh hoạt, React cung cấp các hook và mô hình khác có thể phù hợp hơn tùy thuộc vào nhu cầu cụ thể của bạn. Hãy cùng khám phá một số lựa chọn thay thế như useRef, useReducer và useContext để xem khi nào chúng thực sự hữu ích.

useRef: Lựa chọn thay thế useState khi không cần re-render

Một sai lầm phổ biến của người mới bắt đầu với React là sử dụng useState cho các giá trị không thực sự ảnh hưởng đến quá trình render. useRef là lựa chọn lý tưởng khi bạn cần duy trì dữ liệu qua các lần render mà không kích hoạt re-render.

Ví dụ thực tế:

Hãy tưởng tượng bạn đang theo dõi số lần nhấp vào một nút, nhưng component không cần phải re-render mỗi khi số lần nhấp thay đổi.

function ClickTracker() { const clickCount = useRef(0); const handleClick = () => { clickCount.current += 1; console.log(`Button clicked ${clickCount.current} times`); }; return <button onClick={handleClick}>Click me</button>;
}

Trong trường hợp này, useRef lưu giữ số lần nhấp mà không gây ra re-render không cần thiết. Nếu bạn sử dụng useState, component sẽ re-render sau mỗi lần nhấp, điều này là không cần thiết trong tình huống này.

Vậy khi nào nên chọn useRef:

  • Theo dõi các giá trị không cần kích hoạt cập nhật giao diện người dùng.
  • Lưu trữ tham chiếu đến các phần tử DOM hoặc các giá trị trạng thái trước đó.

useReducer: Giải pháp cho logic trạng thái phức tạp

Đối với logic trạng thái phức tạp hơn, đặc biệt là khi trạng thái của bạn liên quan đến nhiều giá trị con hoặc hành động, useReducer có thể là một giải pháp thay thế mạnh mẽ. useState có thể bắt đầu trở nên cồng kềnh khi bạn quản lý một số phần tử trạng thái phụ thuộc lẫn nhau.

Một tình huống thực tế:

Giả sử bạn đang xây dựng một biểu mẫu, nơi bạn quản lý một số input như tên, email và mật khẩu. Việc sử dụng useState cho mỗi input có thể nhanh chóng trở nên tẻ nhạt.

function formReducer(state, action) { switch (action.type) { case 'SET_NAME': return { ...state, name: action.payload }; case 'SET_EMAIL': return { ...state, email: action.payload }; case 'SET_PASSWORD': return { ...state, password: action.payload }; default: return state; }
} function SignupForm() { const [formState, dispatch] = useReducer(formReducer, { name: '', email: '', password: '' }); return ( <> <input value={formState.name} onChange={(e) => dispatch({ type: 'SET_NAME', payload: e.target.value })} placeholder="Name" /> <input value={formState.email} onChange={(e) => dispatch({ type: 'SET_EMAIL', payload: e.target.value })} placeholder="Email" /> <input value={formState.password} onChange={(e) => dispatch({ type: 'SET_PASSWORD', payload: e.target.value })} placeholder="Password" /> </> );
}

Ở đây, useReducer tập trung tất cả các cập nhật trạng thái vào một hàm duy nhất, giúp việc quản lý dễ dàng hơn so với nhiều lệnh gọi useState.

Vậy khi nào nên chọn useReducer:

  • Xử lý logic trạng thái phức tạp với nhiều giá trị con hoặc hành động.
  • Khi các thay đổi trạng thái tuân theo một luồng dựa trên hành động rõ ràng (ví dụ: SET, ADD, REMOVE).

useContext: Chia sẻ trạng thái giữa các component hiệu quả

Nếu trạng thái của bạn được chia sẻ trên nhiều component, việc truyền props xuống nhiều cấp có thể nhanh chóng trở thành một cơn ác mộng. Đó là lúc useContext phát huy tác dụng — nó giúp bạn chia sẻ trạng thái mà không cần truyền props qua nhiều cấp.

Ví dụ về useContext:

Hãy tưởng tượng bạn đang xây dựng một giỏ hàng. Bạn cần trạng thái của giỏ hàng (các mặt hàng đã thêm, tổng giá, v.v.) có thể truy cập được ở các phần khác nhau của ứng dụng — có thể là tiêu đề, trang thanh toán và bản xem trước giỏ hàng.

const CartContext = React.createContext(); function CartProvider({ children }) { const [cart, setCart] = useState([]); return ( <CartContext.Provider value={{ cart, setCart }}> {children} </CartContext.Provider> );
} function Header() { const { cart } = React.useContext(CartContext); return <div>Items in cart: {cart.length}</div>;
} function App() { return ( <CartProvider> <Header /> {/* Other components */} </CartProvider> );
}

Trong kịch bản này, useContext làm cho trạng thái giỏ hàng có sẵn cho bất kỳ component nào cần đến nó mà không cần truyền props theo cách thủ công.

Vậy khi nào nên chọn useContext:

  • Chia sẻ trạng thái giữa các component được lồng sâu.
  • Tránh việc truyền props cho dữ liệu toàn cục được truy cập phổ biến (ví dụ: xác thực người dùng, chủ đề).

Một cách tiếp cận phù hợp

Mặc dù useState là điểm khởi đầu tuyệt vời, thế nhưng hệ sinh thái của React có thể cung cấp các công cụ mạnh mẽ khác như useRef, useReducer, và useContext có thể giúp đơn giản hóa mã của bạn và cải thiện hiệu suất đáng kể. Thay vì sử dụng useState mặc định, hãy tự hỏi bản thân bạn một vài câu hỏi chính:

  • Trạng thái này có cần kích hoạt kết xuất lại không? (Nếu không, hãy cân nhắc useRef)
  • Logic trạng thái của tôi có trở nên quá phức tạp không useState? (Thử useReducer)
  • Tôi có đang truyền đạo cụ qua quá nhiều thành phần không? (Xem xét useContext)

Bằng cách chọn đúng công cụ cho công việc, bạn sẽ viết được các thành phần React hiệu quả hơn, dễ bảo trì hơn và dễ lập luận hơn.

Vì vậy, lần tới khi bạn thấy mình vẫn đang mặc định sử dụng useState, hãy dừng lại một lát. Có thể sẽ có một cách tốt hơn để xử lý mọi việc!

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 399

- 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 146

- 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 145

- 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 371

- 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 280