Tư duy về thiết kế component cho React app

22 tháng 12, 2020 - 2812 lượt xem

Trong các dự án, việc chia, thiết kế, component có khả năng tái sử dụng cao ảnh hưởng rất nhiều đến tiến độ của dự án. Vậy component là gì?

Trong bài viết này chúng ta sẽ:

- Giới thiệu khái niệm component và container compinent

- Chia nhỏ một app/page ra thành những component ( thành phần ) nhỏ

Tư duy thiết kế components là việc chia app của mình thành những thành phần, mà ở đó mỗi thành phần thực hiện một nhiệm vụ nhất định. Tất cả những gì chúng ta cần là xác định input và output cho thành phần đó.

Chúng ta hãy thử bắt đầu với login form

Trước tiên chúng ta cần bản mock, chúng ta cần xem xét và xác định các thành phần cho nó

 

Sau khi xác định, chúng ta nên sử dụng tên rõ ràng cho mọi "thành phần" (PascalCase theo quy ước React):

LoginForm (màu đỏ): Toàn bộ login form.

SubmitButton (màu xanh): Một nút ( button ) để xác nhận.

Label (pink): cấu trúc của nhãn dán ( label ).

Input (Cam): cấu trúc input.

PasswordInput (xanh sáng): password input.

Chúng ta đã xác định được các compoent, bây giờ hãy xây dựng chúng

const Label = props => <label {...props} />;

const Input = props => <input {...props} />;

const PasswordInput = ({ type = "password", ...props }) => (
  <Input {...{ type, ...props }} />
);

const SubmitButton = ({ type = "submit", ...props }) => (
  <button {...{ type, ...props }} />
);

const LoginForm = props => <form {...props} />;

Để ý, chúng ta có thể sử dụng lại Input trong PasswordInput

Bây giờ chúng ta có những thành phần riêng biệt, chúng ta có thể sử dụng chúng để làm cho login form của chúng ta trở nên sống động. Hãy gọi thành phần gói này là LoginContainer:

const LoginContainer = () => (
  <LoginForm>
    <Label htmlFor="username">Username</Label>
    <Input id="username" name="username" />
    <Label htmlFor="password">Password</Label>
    <PasswordInput id="password" name="password" />
    <SubmitButton>Login</SubmitButton>
  </LoginForm>
);

Form của chúng ta cần tương tác API và eventHandling, nhưng trước tiên ...

Tối ưu hóa từ những bước đầu
Trong khi làm việc trên các component, chúng ta có thể phát hiện các tối ưu hóa, chẳng hạn như mỗi khi chúng ta sử dụng thành phần Input vào hoặc PasswordInput, chúng ta đều thêm Label vào đó, vì vậy để giữ cho sạch, hãy tạo các thành phần để tránh lặp lại:

const FormInput = ({ name, id = `${name}-id`, title, ...props }) => (
  <>
    <Label htmlFor={id}>{title}</Label>
    <Input {...{ id, name, title, ...props }} />
  </>
);

const FormPasswordInput = ({ name, id = `${name}-id`, title, ...props }) => (
  <>
    <Label htmlFor={id}>{title}</Label>
    <PasswordInput {...{ id, name, title, ...props }} />
  </>
);

Đến đây LoginContainer sẽ trông như sau

const LoginContainer = () => (
  <LoginForm>
    <FormInput name="username" title="Username" />
    <FormPasswordInput name="password" title="Password" />
    <SubmitButton>Login</SubmitButton>
  </LoginForm>
);

Thêm State
Nói chung nên để state được ưu tiên cuối cùng, suy nghĩ và thiết kế mọi thứ càng không cần state càng tốt, hiển thị và sử dụng props cụ và event. Nó giúp các component dễ bảo trì, kiểm tra và hiểu tổng thể hơn.

Nếu bạn cần state, nó sẽ được xử lý bởi vùng chứa state (Redux, MobX, unistore, v.v.) hoặc thành phần vùng chứa / trình bao bọc. Trong ví dụ đăng nhập siêu đơn giản này, vị trí cho state chính LoginContainer, hãy sử dụng các hook React cho việc này:

const LoginContainer = () => {
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");

  const login = async event => {
    event.preventDefault();
    const response = await fetch("/api", {
      method: "POST",
      body: JSON.stringify({
        username,
        password,
      }),
    });
    // Here we could check response.status to login or show error
  };

  return (
    <LoginForm onSubmit={login}>
      <FormInput
        name="username"
        title="Username"
        onChange={event => setUsername(event.currentTarget.value)}
        value={username}
      />
      <FormPasswordInput
        name="password"
        title="Password"
        onChange={event => setPassword(event.currentTarget.value)}
        value={password}
      />
      <SubmitButton>Login</SubmitButton>
    </LoginForm>
  );
};

Cách dùng của state tránh có liên quan đến các nguyên tắc chức năng, function.. nhưng về cơ bản là giữ cho các component càng tinh khiết càng tốt.

Tóm lại

Các bước để tư duy và tạo compoent đó là 

1. Tạo bản phác thảo
2. Xác định các component, input và output cho component 
3. Xây dựng chúng.
4. Sử dụng chúng (và tối ưu hóa chúng khi cần thiết).
5. Cố gắng ở trạng thái không state nhất có thể. Chỉ thêm state nếu cần.


Cảm ơn bạn đã đọc! bạn có thể tham khảo khoá học React tại đây. Hoặc bạn tham khảo Lộ trình Web Frontend + ReactJs (sẽ được đào tạo từ cơ bản đến nâng cao về ReactJs)

 

Bình luận

avatar
Quang Tuan Vu 2020-12-23 03:47:10.238618 +0000 UTC
Các bước để tư duy và tạo compoent đó là 1. CHẾ NHẠO là sao ?? :o
Avatar
* Vui lòng trước khi bình luận.
Ảnh đại diện
  0 Thích
0