Розділення проблем за допомогою React перехоплює PlatoBlockchain Data Intelligence. Вертикальний пошук. Ai.

Розділення проблем за допомогою гачків React

Якщо ви деякий час працювали з React, ви, напевно, зіткнулися контейнер та презентаційні компоненти , або розумні та тупі компоненти. Ці терміни описують а модель який відокремлює рівень UI компонентів React від логіки.

Відділення інтерфейсу користувача від бізнес-логіки не є унікальним для React: розділення проблем — це принцип дизайну, який має вже в 70-х роках. Наприклад, звичайною практикою є відокремлення коду, який звертається до бази даних, від бізнес-логіки на сервері.

Тому в React ми вирішили цю проблему, створивши компоненти контейнера, які містять всю логіку, які потім передадуть дані через props до презентаційного компонента.

З появою гачків React з’явився новий підхід до цього: використання гачки на замовлення.

Чому ми повинні відокремлювати логіку від компонента?

Перш ніж ми почнемо відокремлювати логіку від наших компонентів React, ми повинні знати, чому.

Організація нашого коду таким чином, щоб кожна функція або компонент відповідала лише за одне, має перевагу, що це багато легше змінювати та підтримувати (Дейв і Ендрю називають це «ортогональність” у їхній книзі Прагматичний програміст).

Застосування цього до React означає, що наш компонент буде виглядати чистішим і організованішим. Наприклад, нам не потрібно буде прокручувати стіну логіки перед редагуванням інтерфейсу користувача.

Таке впорядкування коду не тільки покращує його вигляд і полегшує навігацію, але також полегшує його зміни, оскільки зміна гачка не впливає на інтерфейс користувача і навпаки.

Тестування також доступніше: ми можемо перевірити логіку окремо від інтерфейсу користувача, якщо хочемо. Однак найважливішою перевагою для мене є те, як цей підхід організовує мій код.

Як роз’єднати логіку за допомогою гачків React

Щоб відокремити логіку від нашого компонента, ми спочатку створимо спеціальний хук.

Візьмемо цей компонент як приклад. Він обчислює експоненцію базового числа та експоненти:

Ви можете знайти повний вихідний код тут.

Код виглядає наступним чином:

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>
  );
};

Це вже може виглядати добре, але заради цього підручника просто картина що тут більше логіки.

Як перший крок, ми це зробимо перемістити логіку до спеціального хука і викликати його всередині нашого компонента.

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();

  // ...
};

Ми могли б перемістити цей гачок на a окремий файл для більш чіткого розділення проблем.

Крім того, ми можемо додатково розділити наш хук на менші, багаторазові функції. У цьому випадку ми можемо лише витягти calculateExponent.

useExponentCalculator.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);

  // ...
};

Тестувати ці функції набагато простіше, ніж тестувати весь код компонента з першого прикладу. Ми могли б перевірити їх за допомогою будь-якої бібліотеки тестування Node.js, яка навіть не потребує підтримки компонентів React.

Тепер у нас є наш специфічний для фреймворка код (React) у коді для компонента та гачка, тоді як наша бізнес-логіка живе в різних функціях, які ми визначили пізніше (які не залежать від фреймворку).

Кращі практики

Іменування

Мені подобається називати свої власні хуки на честь компонента як конкатенації use і назву компонента (напр useExponentCalculator). Тоді я дзвоню файл так само як гачок.

Можливо, ви захочете дотримуватися іншої конвенції щодо імен, але я рекомендую залишаючись послідовними у вашому проекті.

Якщо я можу повторно використати частини спеціального хука, я зазвичай переміщу його в інший файл під src/hooks.

Не перестарайтеся

Намагайтеся бути прагматичними. Якщо компонент містить лише кілька рядків JS, не потрібно відокремлювати логіку.

CSS-в-JS

Якщо ви використовуєте бібліотеку CSS-in-JS (useStyles), ви можете також перемістити цей код в інший файл.

Ви можете перемістити його в той самий файл, що й хук. Однак я віддаю перевагу або тримати його над компонентом у тому самому файлі, або перемістити його у власний файл, якщо він виростає занадто великим.

Висновок

Незалежно від того, чи вважаєте ви, що використання користувальницьких хуків покращує ваш код чи ні, зрештою, все зводиться до особистих уподобань. Якщо ваша кодова база не містить багато логіки, переваги цього шаблону не будуть надто актуальними для вас.

Індивідуальні гачки – це лише один із способів збільшити модульність; Я також дуже рекомендую поділ компонентів і функцій на менші шматки, які можна використовувати повторно коли це можливо.

Ця тема також обговорюється на більш загальному рівні в Прагматичний програміст. Я написав статтю, присвячену моїм улюбленим темам книги, тож якщо це вас зацікавило, обов’язково перевірте це.

Часова мітка:

Більше від Факт React Codementor