Top 7 React Hooks You Must Know
React has revolutionized the way we build user interfaces by introducing a declarative and component-based approach to development. One of its most powerful features is Hooks—a set of functions that allow you to use state and other React features without writing a class component. Hooks were introduced in React 16.8, and they have since become an essential part of every React developer’s toolkit.
In this blog, we will explore the top 7 React hooks that you must know to improve your development workflow and build more efficient, readable, and maintainable React applications.
1. useState
The useState
hook is one of the most commonly used hooks in React. It allows functional components to manage and track their state. Before hooks, state could only be used inside class components, but with useState
, you can now introduce local state to your functional components.
Syntax:
const [state, setState] = useState(initialState);
state
: The current value of the state.
setState
: A function that updates the state.
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>
);
}
export default Counter;
2. useEffect
The useEffect
hook is used to perform side effects in your components. This includes tasks like fetching data, subscribing to external services, or manually changing the DOM. It acts like componentDidMount
, componentDidUpdate
, and componentWillUnmount
combined, but it works for functional components.
Syntax:
useEffect(() => {
// Side effect code
}, [dependencies]);
The first argument is a function that contains the side-effect code.
The second argument is an array of dependencies. If the values inside the array change, the effect will run again. If the array is empty, the effect runs only once, similar to componentDidMount
.
import React, { useState, useEffect } from 'react';
function FetchData() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => setData(data));
}, []); // Empty dependency array means it only runs once
return (
<div>
{data ? <p>{data}</p> : <p>Loading...</p>}
</div>
);
}
export default FetchData;
3. useContext
The useContext
hook allows you to access values from the context without needing to wrap your component in a <Context.Consumer>
.
Context in React is used for sharing values (like themes, user information, or language settings) between components without having to explicitly pass props down the tree.
Syntax:
const value = useContext(MyContext);
import React, { createContext, useContext } from 'react';
const ThemeContext = createContext('light');
function ThemedComponent() {
const theme = useContext(ThemeContext);
return <div className={theme}>This is a {theme} themed component!</div>;
}
function App() {
return (
<ThemeContext.Provider value="dark">
<ThemedComponent />
</ThemeContext.Provider>
);
}
export default App;
4. useReducer
The useReducer
hook is an alternative to useState
for managing more complex state logic, such as when the state depends on the previous state or involves multiple actions. It’s especially useful for handling state in large applications.
Syntax:
const [state, dispatch] = useReducer(reducer, initialState);
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:
return state;
}
}
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>
);
}
export default Counter;
5. useRef
The useRef
hook is primarily used to persist values across renders. It can be used to store a reference to a DOM element or any value that doesn’t trigger a re-render when it’s updated.
Syntax:
const myRef = useRef(initialValue);
import React, { useRef } from 'react';
function FocusInput() {
const inputRef = useRef();
const handleFocus = () => {
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={handleFocus}>Focus the input</button>
</div>
);
}
export default FocusInput;
6. useMemo
The useMemo
hook is used to optimize performance by memoizing expensive calculations. It only recomputes the memoized value when one of the dependencies changes. This is useful for avoiding unnecessary recalculations in large applications.
Syntax:
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
import React, { useState, useMemo } from 'react';
function ExpensiveCalculation() {
const [number, setNumber] = useState(1);
const computeExpensiveValue = (num) => {
console.log('Computing...');
return num * 2;
};
const memoizedValue = useMemo(() => computeExpensiveValue(number), [number]);
return (
<div>
<p>Result: {memoizedValue}</p>
<button onClick={() => setNumber(number + 1)}>Increment</button>
</div>
);
}
export default ExpensiveCalculation;
7. useCallback
The useCallback
hook is similar to useMemo
but is used specifically for memoizing functions. It ensures that a function is not recreated on every render unless its dependencies change, which can improve performance when passing functions as props to child components.
Syntax:
const memoizedCallback = useCallback(() => { /* function body */ }, [dependencies]);
import React, { useState, useCallback } from 'react';
function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log('Button clicked');
}, []);
return (
<div>
<Child onClick={handleClick} />
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
function Child({ onClick }) {
return <button onClick={onClick}>Click me</button>;
}
export default Parent;
React hooks are a game changer for developers, allowing us to manage state, side effects, and memoization more efficiently. The useState, useEffect, useContext, useReducer, useRef, useMemo, and useCallback hooks are just a few of the essential hooks that every React developer should master.
By incorporating these hooks into your applications, you can build cleaner, more performant, and easier-to-maintain codebases. As you grow more familiar with React, experimenting with these hooks and their various use cases will help you become a more effective and efficient developer. Happy coding!