Skip to main content

Command Palette

Search for a command to run...

Understanding React Hooks: useState, useEffect and Custom Hooks Explained

Updated
5 min read
Understanding React Hooks: useState, useEffect and Custom Hooks Explained
A
Hey, I'm Funmibi — a self-taught frontend developer from Lagos, Nigeria. I build responsive, fast, and clean websites that help small businesses and startups show up professionally online. I write practical web dev tutorials on my blog to help other developers grow. If you need a website or want to collaborate, reach out at funmibitech@gmail.com

Before hooks React was split into two worlds.

Class components that could manage state and lifecycle methods. Functional components that were simpler but couldn't do much beyond displaying UI.

Hooks changed everything. Now you can manage state, handle side effects and share reusable logic all from simple functions. No classes. No confusion.

Here are the three most important hooks every React developer needs to understand.

useState — Managing State in Your Components

State is data that changes over time and causes your UI to update when it does. useState is how you manage that data in a functional component.

When you call useState you get back two things — the current value of the state and a function to update it. When you call the update function React re-renders the component with the new value.

A simple example is a counter. You start with a value of zero. Every time the user clicks a button you call the update function with the new value. React sees the change and updates what's displayed on screen automatically.

The most common mistake beginners make is trying to update state directly by reassigning the variable instead of using the setter function. React doesn't watch your variables — it only knows something changed when you use the setter. Always use the setter function.

The second common mistake is using the current state value directly inside the setter when the new value depends on the previous one. Instead pass a function to the setter that receives the previous value and returns the new one. This keeps your updates accurate even when React batches multiple updates together.

useEffect — Handling Side Effects

A side effect is anything your component does that reaches outside of React. Fetching data from an API. Setting up a subscription. Starting a timer. Directly manipulating the DOM. All of these are side effects and useEffect is where they belong.

useEffect runs after the component renders. You pass it a function containing your side effect and React runs it after every render by default.

The dependency array is where most beginners get confused. It's the second argument you pass to useEffect and it controls when the effect runs.

No dependency array means the effect runs after every single render. Usually not what you want.

An empty dependency array means the effect runs only once — after the first render. Perfect for fetching initial data.

A dependency array with specific values means the effect runs again whenever those values change. Useful for re-fetching data when a search term or user ID changes.

The most dangerous mistake with useEffect is creating an infinite loop. This happens when you update state inside useEffect without a dependency array — the state update triggers a re-render, the re-render triggers the effect, the effect updates state again and it loops forever. Always think carefully about your dependency array.

Also clean up after your effects when necessary. If you start a timer or subscription inside useEffect return a cleanup function that stops it. Otherwise you get memory leaks when the component unmounts.

Custom Hooks — Reusable Logic Across Components

Custom hooks are where React development starts to feel really clean.

Imagine you have three different components that all need to fetch data from an API. Without custom hooks you write the same useEffect and useState logic in all three. When something changes you update it in three places.

With a custom hook you extract that logic into a single function — call it useFetch — and use it in all three components. When something changes you update it in one place.

That's all a custom hook is. A function that starts with "use" and contains other hooks inside it. React recognizes the "use" prefix and applies the rules of hooks to it automatically.

A useFetch hook typically manages three pieces of state — the data returned from the API, a loading boolean that's true while the request is in progress and an error value if something goes wrong. Any component that needs to fetch data just calls useFetch with a URL and gets back those three values ready to use.

Custom hooks make your components cleaner, your logic reusable and your codebase easier to maintain.

The Rules of Hooks

Two rules that you must never break:

Only call hooks at the top level of your component. Never inside loops, conditions or nested functions. React relies on hooks being called in the same order every render — breaking this causes bugs that are very hard to track down.

Only call hooks inside React functions. Either inside a functional component or inside another custom hook. Never in regular JavaScript functions.

When to Use Which

useState — any time you need your UI to react to changing data. A form input value. A toggle. A counter. A list that the user can modify.

useEffect — any time your component needs to interact with something outside of React. An API call. A timer. An event listener. A browser API.

Custom hooks — any time you find yourself writing the same hook logic in more than one component. Extract it, name it with "use" and share it everywhere you need it.

Conclusion

Hooks are not complicated once you understand what problem each one solves.

useState manages data that changes over time. useEffect handles everything outside of React. Custom hooks share logic across your components without repeating yourself.

Master these three and you understand 80% of how modern React works. Everything else builds on top of this foundation.

Which React hook gave you the most trouble when you first learned it? Drop it in the comments — let's help each other past the confusing parts.