Tách biệt mối quan tâm với React móc PlatoBlockchain Data Intelligence. Tìm kiếm dọc. Ái.

Tách biệt mối quan tâm với React hook

Nếu bạn đã làm việc với React một thời gian, chắc chắn bạn đã gặp chứathành phần trình bày hoặc các thành phần thông minh và câm. Những thuật ngữ này mô tả một Belt Hold phân chia lớp giao diện người dùng của các thành phần React khỏi logic.

Việc tách giao diện người dùng khỏi logic nghiệp vụ không phải là điều độc nhất đối với React: việc tách các mối quan tâm là một nguyên tắc thiết kế có đã có từ những năm 70. Ví dụ: thông lệ là tách mã truy cập cơ sở dữ liệu khỏi logic nghiệp vụ ở phần phụ trợ.

Vì vậy, trong React, chúng tôi đã giải quyết vấn đề này bằng cách tạo các thành phần vùng chứa chứa tất cả logic, sau đó sẽ truyền dữ liệu qua các đạo cụ đến thành phần trình bày.

Với sự ra đời của React hook, có một cách tiếp cận mới cho vấn đề này: sử dụng móc tùy chỉnh.

Tại sao chúng ta nên tách logic khỏi thành phần?

Trước khi bắt đầu tách logic khỏi các thành phần React, chúng ta nên biết lý do tại sao.

Việc tổ chức mã của chúng ta theo cách mà mọi chức năng hoặc thành phần chỉ chịu trách nhiệm về một thứ có lợi thế là nó có nhiều chức năng hơn. dễ dàng thay đổi và bảo trì hơn (Dave và Andrew gọi đây là “tính trực giao” trong cuốn sách của họ Lập trình viên thực dụng).

Áp dụng điều này vào React có nghĩa là thành phần của chúng ta sẽ trông gọn gàng và ngăn nắp hơn. Chẳng hạn, chúng ta sẽ không cần phải cuộn qua bức tường logic trước khi chỉnh sửa giao diện người dùng.

Việc sắp xếp mã của bạn như thế này không chỉ giúp mã trông đẹp hơn và dễ điều hướng hơn mà còn giúp thay đổi dễ dàng hơn vì việc thay đổi hook không ảnh hưởng đến giao diện người dùng và ngược lại.

Việc kiểm tra cũng dễ tiếp cận hơn: chúng tôi có thể kiểm tra logic riêng biệt với giao diện người dùng nếu muốn. Tuy nhiên, lợi thế đáng kể nhất đối với tôi là cách tiếp cận này tổ chức mã của tôi.

Cách tách logic bằng móc React

Để tách logic khỏi thành phần của chúng tôi, trước tiên chúng tôi sẽ tạo một hook tùy chỉnh.

Hãy lấy thành phần này làm ví dụ. Nó tính giá trị hàm mũ của số cơ sở và số mũ:

Bạn có thể tìm thấy mã nguồn hoàn chỉnh tại đây.

Mã trông giống như sau:

export const ExponentCalculator = () => {
  const [base, setBase] = useState(4);
  const [exponent, setExponent] = useState(4);
  const result = (base ** exponent).toFixed(2);

  const handleBaseChange = (e) => {
    e.preventDefault();
    setBase(e.target.value);
  };

  const handleExponentChange = (e) => {
    e.preventDefault();
    setExponent(e.target.value);
  };

  return (
    <div className="blue-wrapper">
      <input
        type="number"
        className="base"
        onChange={handleBaseChange}
        placeholder="Base"
        value={base}
      />
      <input
        type="number"
        className="exponent"
        onChange={handleExponentChange}
        placeholder="Exp."
        value={exponent}
      />
      <h1 className="result">{result}</h1>
    </div>
  );
};

Điều này có thể trông ổn rồi, nhưng vì mục đích của hướng dẫn này, chỉ cần hình ảnh rằng có nhiều logic hơn ở đây.

Bước đầu tiên, chúng tôi sẽ di chuyển logic đến một hook tùy chỉnh và gọi nó bên trong thành phần của chúng tôi.

const useExponentCalculator = () => {
  const [base, setBase] = useState(4);
  const [exponent, setExponent] = useState(4);
  const result = (base ** exponent).toFixed(2);

  const handleBaseChange = (e) => {
    e.preventDefault();
    setBase(e.target.value);
  };

  const handleExponentChange = (e) => {
    e.preventDefault();
    setExponent(e.target.value);
  };

  return {
    base,
    exponent,
    result,
    handleBaseChange,
    handleExponentChange,
  };
};

export const ExponentCalculator = () => {
  const {
    base,
    exponent,
    result,
    handleExponentChange,
    handleBaseChange,
  } = useExponentCalculator();

  // ...
};

Chúng ta có thể di chuyển cái móc này đến một tập tin riêng biệt để có sự phân tách mối quan tâm nổi bật hơn.

Ngoài ra, chúng ta có thể tách hook của mình thành các hàm nhỏ hơn, có thể tái sử dụng. Trong trường hợp này, chúng ta chỉ có thể trích xuất calculateExponent.

useExentCalculator.js

const calculateExponent = (base, exponent) => base ** exponent;

const useExponentCalculator = () => {
  const [base, setBase] = useState(4);
  const [exponent, setExponent] = useState(4);
  const result = calculateExponent(base, exponent).toFixed(2);

  // ...
};

Việc kiểm tra các chức năng này dễ dàng hơn nhiều so với việc kiểm tra toàn bộ mã của thành phần từ ví dụ đầu tiên. Chúng tôi có thể thử nghiệm chúng với bất kỳ thư viện thử nghiệm Node.js nào, thậm chí không cần hỗ trợ các thành phần React.

Bây giờ chúng tôi có mã dành riêng cho khung (React) trong mã cho thành phần và hook, trong khi logic nghiệp vụ của chúng tôi tồn tại trong các hàm khác nhau mà chúng tôi đã xác định sau này (là những hàm bất khả tri về khung).

Các phương pháp hay nhất

Đặt tên

Tôi muốn đặt tên cho các hook tùy chỉnh của mình theo thành phần này như một sự kết hợp của use và tên của thành phần (ví dụ useExponentCalculator). Sau đó tôi gọi tập tin tương tự như cái móc.

Bạn có thể muốn tuân theo một quy ước đặt tên khác, nhưng tôi khuyên bạn nên luôn kiên định trong dự án của bạn.

Nếu tôi có thể sử dụng lại các phần của một hook tùy chỉnh, tôi thường di chuyển nó sang một tệp khác trong src/hooks.

Đừng làm quá

Hãy cố gắng thực dụng. Nếu một thành phần chỉ có một vài dòng JS thì không cần thiết phải tách logic.

CSS-trong-JS

Nếu bạn đang sử dụng thư viện CSS-in-JS (useStyles), bạn cũng có thể muốn di chuyển mã này sang một tệp khác.

Bạn có thể di chuyển nó vào cùng tập tin với hook. Tuy nhiên, tôi thích giữ nó phía trên thành phần trong cùng một tệp hoặc di chuyển nó vào tệp riêng nếu nó phát triển quá lớn.

Kết luận

Cho dù bạn có nghĩ rằng việc sử dụng móc tùy chỉnh sẽ cải thiện mã của mình hay không thì cuối cùng, điều đó tùy thuộc vào sở thích cá nhân. Nếu cơ sở mã của bạn không chứa nhiều logic thì ưu điểm của mẫu này sẽ không quá phù hợp với bạn.

Móc tùy chỉnh chỉ là một cách để tăng tính mô đun; Tôi cũng rất muốn giới thiệu chia các thành phần và chức năng thành các phần nhỏ hơn, có thể tái sử dụng khi có thể.

Chủ đề này cũng được thảo luận ở mức độ tổng quát hơn trong Lập trình viên thực dụng. Tôi đã viết một bài viết về các chủ đề tôi yêu thích trong cuốn sách, vì vậy nếu điều đó khiến bạn quan tâm, hãy đảm bảo kiểm tra xem.

Dấu thời gian:

Thêm từ Sự thật về phản ứng của Codementor