0
0
Lập trình
Thaycacac
Thaycacac thaycacac

✨ Các Mô Hình React Mà Chuyên Gia Nên Thành Thạo 🧩🪝

Đăng vào 4 tháng trước

• 6 phút đọc

Khám Phá Các Mô Hình React Quan Trọng

React không chỉ đơn thuần là viết các thành phần (components) mà còn là cách viết chúng theo những cách có thể mở rộng, tái sử dụng và dễ bảo trì. Đó là lý do tại sao các mô hình thiết kế trở nên quan trọng. Hãy cùng khám phá các mô hình React quan trọng nhất, kèm theo ví dụ, trường hợp sử dụng thực tế và lý do chúng có ý nghĩa như thế nào. 🌟

1️⃣ Mô Hình Container & Presentational 🧑‍💻🎨

  • Container Components: Xử lý việc lấy dữ liệu, trạng thái và logic kinh doanh.
  • Presentational Components: Chỉ xử lý việc hiển thị giao diện.

👉 Trường hợp sử dụng: Giữ cho mã sạch sẽ bằng cách tách logic ra khỏi giao diện.

javascript Copy
// Presentational
const UserList = ({ users }) => (
  <ul>{users.map(u => <li key={u.id}>{u.name}</li>)}</ul>
);

// Container
const UserListContainer = () => {
  const [users, setUsers] = useState([]);
  useEffect(() => {
    fetch("/api/users").then(res => res.json()).then(setUsers);
  }, []);
  return <UserList users={users} />;
};

Trường hợp thực tế: Một thành phần UserProfile chỉ hiển thị dữ liệu, trong khi UserProfileContainer thực hiện việc lấy dữ liệu từ API.


2️⃣ Higher-Order Components (HOC) 🔁

Một hàm nhận một thành phần và trả về một thành phần mới với chức năng mở rộng.

👉 Trường hợp sử dụng: Tái sử dụng mã (ví dụ: xác thực, ghi log, chủ đề).

javascript Copy
const withLogger = (Wrapped) => (props) => {
  useEffect(() => console.log("Mounted:", Wrapped.name), []);
  return <Wrapped {...props} />;
};

const Profile = () => <h2>My Profile</h2>;
export default withLogger(Profile);

Trường hợp thực tế: HOC withAuth để bảo vệ các tuyến đường.


3️⃣ Render Props 🎭

Một mô hình mà con cái của một thành phần là một hàm nhận trạng thái/logic.

👉 Trường hợp sử dụng: Chia sẻ hành vi mà không cần kế thừa hoặc HOC.

javascript Copy
const MouseTracker = ({ children }) => {
  const [pos, setPos] = useState({ x: 0, y: 0 });
  return (
    <div onMouseMove={(e) => setPos({ x: e.clientX, y: e.clientY })}>
      {children(pos)}
    </div>
  );
};

<MouseTracker>
  {({ x, y }) => <h1>🐭 Chuột: {x}, {y}</h1>}
</MouseTracker>

Trường hợp thực tế: Tooltip, kéo và thả, theo dõi phân tích.


4️⃣ Custom Hooks 🪝

Đóng gói logic trong các hooks có thể tái sử dụng.

👉 Trường hợp sử dụng: Trích xuất logic trạng thái từ các thành phần để tái sử dụng.

javascript Copy
const useFetch = (url) => {
  const [data, setData] = useState(null);
  useEffect(() => {
    fetch(url).then(r => r.json()).then(setData);
  }, [url]);
  return data;
};

const Posts = () => {
  const posts = useFetch("/api/posts");
  return posts ? posts.map(p => <p key={p.id}>{p.title}</p>) : "⏳ Đang tải...";
};

Trường hợp thực tế: useAuth, useLocalStorage, useDebounce.


5️⃣ Compound Components 🧩

Một tập hợp các thành phần làm việc cùng nhau để cung cấp một API linh hoạt.

👉 Trường hợp sử dụng: Các thư viện UI linh hoạt như react-router, headlessui, Radix UI.

javascript Copy
const Tabs = ({ children }) => <div>{children}</div>;
Tabs.Tab = ({ children }) => <button>{children}</button>;
Tabs.Panel = ({ children }) => <div>{children}</div>;

<Tabs>
  <Tabs.Tab>🏠 Trang chủ</Tabs.Tab>
  <Tabs.Tab>👤 Hồ sơ</Tabs.Tab>
  <Tabs.Panel>Nội dung cho Trang chủ</Tabs.Panel>
  <Tabs.Panel>Nội dung cho Hồ sơ</Tabs.Panel>
</Tabs>;

Trường hợp thực tế: Menu dropdown, modal, biểu mẫu từng bước.


6️⃣ Context API / Provider Pattern 🌐

Được sử dụng để chia sẻ trạng thái toàn cục mà không cần truyền props.

👉 Trường hợp sử dụng: Chủ đề, xác thực, cài đặt toàn cục.

javascript Copy
const ThemeContext = createContext("light");

const ThemeProvider = ({ children }) => {
  const [theme, setTheme] = useState("light");
  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      {children}
    </ThemeContext.Provider>
  );
};

const ThemedButton = () => {
  const { theme } = useContext(ThemeContext);
  return <button>{theme === "light" ? "☀️ Chế độ sáng" : "🌙 Chế độ tối"}</button>;
};

Trường hợp thực tế: Chế độ tối/sáng, phiên người dùng, chuyển đổi ngôn ngữ.


7️⃣ Controlled vs Uncontrolled Components 🎛️

  • Controlled: Giá trị biểu mẫu được kiểm soát thông qua trạng thái React.
  • Uncontrolled: Giá trị biểu mẫu được truy cập thông qua refs.

👉 Trường hợp sử dụng: Controlled để xác thực, uncontrolled cho hiệu suất hoặc biểu mẫu đơn giản.

javascript Copy
// Controlled
<input value={value} onChange={(e) => setValue(e.target.value)} />

// Uncontrolled
<input ref={ref} />

Trường hợp thực tế:

  • ✅ Controlled: Biểu mẫu đăng ký với xác thực trực tiếp.
  • ✅ Uncontrolled: Nhập liệu tải lên tệp.

8️⃣ State Reducer Pattern ⚙️

Cho phép người tiêu dùng kiểm soát các chuyển tiếp trạng thái nội bộ (lấy cảm hứng từ Redux).

👉 Trường hợp sử dụng: Các thành phần có thể tái sử dụng phức tạp mà người dùng cần kiểm soát.

javascript Copy
function useToggle({ reducer = (s, a) => !s } = {}) {
  const [on, dispatch] = useReducer(reducer, false);
  return [on, () => dispatch()];
}

Trường hợp thực tế: Cách chuyển đổi, dropdown, hoặc logic modal có thể tùy chỉnh.


9️⃣ Controlled Props Pattern 🎚️

Thành phần chấp nhận cả kiểm soát trạng thái nội bộ và bên ngoài.

👉 Trường hợp sử dụng: Các thành phần thư viện cần sự linh hoạt trong việc sử dụng.

javascript Copy
const Toggle = ({ on: controlledOn, onChange }) => {
  const [uncontrolledOn, setOn] = useState(false);
  const isControlled = controlledOn !== undefined;
  const on = isControlled ? controlledOn : uncontrolledOn;

  const toggle = () => {
    if (isControlled) onChange(!on);
    else setOn(!on);
  };

  return <button onClick={toggle}>{on ? "✅ BẬT" : "❌ TẮT"}</button>;
};

Trường hợp thực tế: Cách chuyển đổi có thể tái sử dụng, các thành phần biểu mẫu, inputs.


🔟 Hooks State Machine Pattern 🕹️

Mô hình hành vi thành phần với máy trạng thái hữu hạn.

👉 Trường hợp sử dụng: Quy trình UI phức tạp với nhiều trạng thái.

javascript Copy
function useToggleMachine() {
  const [state, setState] = useState("off");
  const toggle = () => setState(state === "off" ? "on" : "off");
  return { state, toggle };
}

Trường hợp thực tế: Quy trình thanh toán 💳, quy trình onboarding từng bước 🪜, xác thực 🔑.


🧭 Lựa Chọn Mô Hình React Phù Hợp

mermaid Copy
flowchart TD
    A[Khởi đầu: Cần chia sẻ hoặc tái sử dụng logic?] -->|Có| B[Custom Hook]
    A -->|Không| C[Cần tái sử dụng UI?]

    C -->|Có| D[Các thành phần hợp thành]
    C -->|Không| E[Chia sẻ trạng thái phức tạp?]

    E -->|Có| F[Context API / Mô Hình Provider]
    E -->|Không| G[Trạng thái cục bộ cho thành phần]

    B --> H[Hook có thể tái sử dụng qua các thành phần]
    D --> I[UI linh hoạt & có thể kết hợp]
    F --> J[Trạng thái hoặc chủ đề toàn cục]
    G --> K[Hook useState đơn giản]

🏁 Những Suy Nghĩ Cuối Cùng ✨

Các mô hình không chỉ là “kiến thức cần biết” mà chúng là điều phân biệt các nhà phát triển React giỏi với các nhà phát triển xuất sắc. Bằng cách thành thạo chúng, bạn sẽ xây dựng các ứng dụng có khả năng mở rộng tốt, dễ bảo trì hơn và cung cấp API sạch cho nhóm của bạn và chính bạn trong tương lai. 💡

🔥 Bắt đầu từ những điều nhỏ, tái cấu trúc từng bước và để các mô hình xuất hiện một cách tự nhiên.


📝 Về Tác Giả

Viết bởi Yogesh Bamanier - Nhà phát triển Frontend cấp cao | Chuyên gia React.js | Người đóng góp mã nguồn mở Đam mê xây dựng các ứng dụng React có khả năng mở rộng và chia sẻ kiến thức với cộng đồng phát triển. 🚀


🏷️📢 Học Tập Vui Vẻ...

  • #reactjs
  • #javascript
  • #frontend
  • #webdev
  • #reactpatterns
  • #hooks
Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào