Devs Hive
Повернутися до всіх запитань

Яку проблему вирішують Hooks в React?

JuniorMiddleReact.js
Зустрічали на інтервʼю:1 користувач

Це запитання часто ставлять на Junior/Middle interview і воно показує як глибоко ви розбирались з тим, навіщо взагалі придумали React Hooks.

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

Розберемо приклад

Уявимо, що в нас є так званий Toggle, який переключає стан кнопки. Наразі ми його використовуємо в одному компоненті і він не створює проблем.

class ToggleButton extends React.Component {
state = { on: false };

toggle = () => {
this.setState((s) => ({ on: !s.on }));
};

render() {
return (
<button onClick={this.toggle}>
{this.state.on ? "ON" : "OFF"}
</button>
);
}
}

Але пізніше в нас зʼявляється необхідність додати такий самий функціонал для модальних вікон. І якраз тут заключається основна проблема класових компонентів. Так як this.state привʼязаний до конкретного класу, ми не можемо перевикористати бізнес логіку в іншому компоненті. Тоді нам доводиться писати костилі. Найпоширеніші це: render props, наслідування i HOC. Останнє є найбільш адекватним з даного списку і доволі часто виручало, але сильно ускладнювало кодову базу.

З хуками ситуація стала набагато кращою і ми можемо винести всю логіку переключення в Custom Hook і перевикористовувати як в кнопці так і в модальному вікні.

import * as React from "react";

function useToggle(initial = false) {
const [on, setOn] = React.useState(initial);

const toggle = React.useCallback(() => {
setOn((v) => !v);
}, []);

const setTrue = React.useCallback(() => setOn(true), []);
const setFalse = React.useCallback(() => setOn(false), []);

return { on, toggle, setTrue, setFalse };
}

// Перевикористовуємо стан
function ToggleButton() {
const { on, toggle } = useToggle(false);

return <button onClick={toggle}>{on ? "ON" : "OFF"}</button>;
}

function Modal() {
const { on, setTrue, setFalse } = useToggle(false);

return (
<div>
<button onClick={setTrue}>Open modal</button>

{on && (
<div style={{ border: "1px solid #ccc", padding: 12 }}>
<p>Modal content</p>
<button onClick={setFalse}>Close</button>
</div>
)}
</div>
);
}

Зустрічав на інтервʼю?

Коментарі (0)

Увійдіть, щоб залишити коментар

Поки що немає коментарів. Будьте першим!