6 Important React Hooks: Explained
I am a Frontend Web developer & a UI/UX Designer from India and I completed my graduation in Computer Science.
I am well-versed in Java, C, C++, Python, JavaScript, HTML, CSS, ReactJs, NodeJS, MySQL, and MongoDB.
I am eager to learn new technologies/frameworks and I strive hard in giving my 100% effort into building something new. In the future, I see myself as a successful Software Engineer. I want to teach and mentor students about coding and new technologies.
React is a popular JavaScript library for building user interfaces. Hooks are a new addition to React that allow you to use state and other React features without writing a class. Hooks are a powerful tool that can simplify your code and make it easier to read and maintain. In this article, we will explore six important hooks in React and explain how they work.
- useState()
useState() is the most commonly used hook in React. It allows you to add a state to your functional components. State is an object that contains data that can change over time. You can use the useState() hook to create a state variable and update it with a setter function. Here is an example:
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
In the example above, we use the useState() hook to create a state variable called count and a setter function called setCount. We initialize the state to 0. When the button is clicked, we update the state by calling the setCount function with the new value.
- useEffect()
useEffect() is another important hook in React. It allows you to perform side effects on your functional components. Side effects are actions that affect the outside world, such as fetching data from an API or updating the title of the page. Here is an example:
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
In the example above, we use the useEffect() hook to update the title of the page whenever the count state changes. The useEffect() hook takes a function as its first parameter. This function is called after every render. We can use it to perform side effects like updating the title.
- useContext()
useContext() allows you to access context in your functional components. Context is a way to pass data down the component tree without having to pass props down manually at every level. Here is an example:
import React, { useContext } from 'react';
const ThemeContext = React.createContext('light');
function App() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
const theme = useContext(ThemeContext);
return (
<div>
<button style={{ background: theme === 'dark' ? 'black' : 'white', color: theme === 'dark' ? 'white' : 'black' }}>
Click me
</button>
</div>
);
}
In the example above, we create a context using React.createContext(). We provide a default value of 'light'. In the App component, we wrap the Toolbar component in a ThemeContext.Provider and set the value to 'dark'. In the Toolbar component, we use the useContext() hook to access the value of the context. We can use this value to style our button based on the current theme.
- useReducer()
useReducer() is a hook that allows you to manage complex state in your functional components. It works by dispatching actions to a reducer function that updates the state based on the action. Here is an example:
import React, { useReducer } from 'react';
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>
Increment
</button>
<button onClick={() => dispatch({ type: 'decrement' })}>
Decrement
</button>
</div>
);
}
In the example above, we create an initial state object with a count property set to 0. We also create a reducer function that takes the current state and an action object as its parameters. The reducer function updates the state based on the action type. We use the useReducer() hook to create a state object and a dispatch function. We pass the reducer function and the initial state object to the useReducer() hook. In the Counter component, we render the current count and two buttons that dispatch actions to the reducer function.
- useCallback()
useCallback() is a hook that memoizes functions in your functional components. Memoization is a technique that caches the results of expensive function calls to improve performance. Here is an example:
import React, { useState, useCallback } from 'react';
function ChildComponent({ callback }) {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
<button onClick={() => callback(count)}>
Call parent callback
</button>
</div>
);
}
function ParentComponent() {
const [result, setResult] = useState(null);
const callback = useCallback((count) => {
setResult(count);
}, []);
return (
<div>
<ChildComponent callback={callback} />
{result && <p>Result: {result}</p>}
</div>
);
}
In the example above, we create a ChildComponent that renders a count and two buttons. One button increments the count and the other calls a callback function with the current count. We also create a ParentComponent that renders the ChildComponent and a result message. The ParentComponent has a callback function that sets the result state when called. We use the useCallback() hook to memoize the callback function. This ensures that the function is only recreated when the dependencies change. In this case, there are no dependencies, so the function is only created once.
- useMemo()
useMemo() is a hook that memoizes values in your functional components. It works by caching the result of an expensive function call and returning the cached value on subsequent renders. Here is an example:
import React, { useMemo, useState } from 'react';
function ExpensiveComponent({ list }) {
const result = useMemo(() => {
return list.reduce((sum, item) => sum + item, 0);
}, [list]);
return <p>Result: {result}</p>;
}
function ParentComponent() {
const [list, setList] = useState([1, 2, 3, 4, 5]);
return (
<div>
<ExpensiveComponent list={list} />
<button onClick={() => setList([...list, Math.floor(Math.random() * 10)])}>
Add item
</button>
</div>
)
}
In the example above, we create an ExpensiveComponent that takes a list of numbers as a prop. The component uses the useMemo() hook to memoize the result of a function that calculates the sum of the numbers in the list. The useMemo() hook only recomputes the result when the list prop changes. We also create a ParentComponent that has a list state and a button to add a random number to the list. When the button is clicked, the ParentComponent adds a new number to the list, causing the ExpensiveComponent to re-render with the updated result.
Conclusion
React hooks are a powerful feature that enables developers to write more reusable and efficient code. In this article, we covered six important React hooks: useState(), useEffect(), useContext(), useReducer(), useCallback(), and useMemo(). Each hook serves a specific purpose and can be used to solve a wide range of problems. By mastering these hooks, you can write more maintainable and performant React code.
Thanks for reading. If you like this blog post, then please share it with others as well.
Follow around to get more such insightful on similar topics like this one.




