Back to all questions

What problem do Hooks solve in React?

JuniorMiddleReact.js
Seen on interview:1 user

Question is often asked in Junior/Middle interviews and it shows how deeply you’ve understood why React Hooks were introduced in the first place.

If we go back to the era of class components, we can see an obvious problem: state is tightly coupled to a specific component, and we can’t reuse it. Of course, people found workarounds - using inheritance or mixins - but that usually made things worse rather than solving the problem.

Let’s look at an example

Imagine we have a so-called Toggle that switches a button’s state. Right now, we use it in one component and it doesn’t cause any issues.

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

But later, we need to add the same functionality for modal windows. And this is exactly where the main problem with class components shows up. Since this.state is tied to a specific class, we can’t reuse that logic in another component.

So we end up writing workarounds. The most common ones are render props, inheritance, and HOCs. The last one is the most reasonable option on that list and often helped, but it made the codebase more complex.

With Hooks, the situation improved: we can extract all the toggle logic into a custom hook and reuse it in both a button and a modal window.

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

// Reuse the state
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>
);
}


Seen on interview?

Comments (0)

Sign in to leave a comment

No comments yet. Be the first!