React hooks are functions that let you "hook into" React state and lifecycle features in functional components. Introduced in React 16.8, they enable you to use state and other React features without writing class components.
In this blog post, we’ll go through each of the commonly used React hooks and provide basic examples to illustrate their functionality.
1. useState
The useState
hook lets you add state to a functional component.
Example:
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0); // Initialize state with 0
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
2. useEffect
The useEffect
hook allows you to perform side effects in your components, such as data fetching or updating the DOM.
In React (or any programming context), a side effect refers to any operation that affects something outside the scope of the current function or computation. In React components, side effects are actions that interact with the outside world or modify the component's environment, rather than simply returning a value.
Example:
import React, { useState, useEffect } from 'react';
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSeconds((prev) => prev + 1);
}, 1000);
return () => clearInterval(interval); // Cleanup on unmount
}, []); // Empty dependency array means this effect runs once
return <p>Time: {seconds}s</p>;
}
3. useContext
The useContext
hook provides a way to access values from a context without using Context.Consumer
.
Example:
import React, { useContext, createContext } from 'react';
const ThemeContext = createContext('light');
function ThemedComponent() {
const theme = useContext(ThemeContext);
return <p>Current theme: {theme}</p>;
}
function App() {
return (
<ThemeContext.Provider value="dark">
<ThemedComponent />
</ThemeContext.Provider>
);
}
4. useReducer
The useReducer
hook is an alternative to useState
for managing more complex state logic.
Example:
import React, { useReducer } from 'react';
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, { count: 0 });
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</div>
);
}
5. useRef
The useRef
hook lets you persist a mutable value across renders or directly access a DOM element.
Example:
import React, { useRef } from 'react';
function FocusInput() {
const inputRef = useRef(null);
const focusInput = () => {
inputRef.current.focus(); // Focus the input element
};
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={focusInput}>Focus Input</button>
</div>
);
}
6. useMemo
The useMemo
hook memoizes a value to avoid unnecessary recalculations.
Example:
import React, { useState, useMemo } from 'react';
function ExpensiveComputation({ num }) {
const compute = (n) => {
console.log('Computing...');
return n * 2;
};
const memoizedValue = useMemo(() => compute(num), [num]);
return <p>Computed value: {memoizedValue}</p>;
}
function App() {
const [num, setNum] = useState(5);
return (
<div>
<button onClick={() => setNum((prev) => prev + 1)}>Increase</button>
<ExpensiveComputation num={num} />
</div>
);
}
7. useCallback
The useCallback
hook memoizes a function so that it doesn't get re-created on every render.
Example:
import React, { useState, useCallback } from 'react';
function Button({ onClick }) {
return <button onClick={onClick}>Click me</button>;
}
function App() {
const [count, setCount] = useState(0);
const increment = useCallback(() => setCount((prev) => prev + 1), []);
return (
<div>
<p>Count: {count}</p>
<Button onClick={increment} />
</div>
);
}
8. useLayoutEffect
Similar to useEffect
, but it fires synchronously after DOM mutations.
Example:
import React, { useRef, useLayoutEffect } from 'react';
function Box() {
const boxRef = useRef();
useLayoutEffect(() => {
boxRef.current.style.color = 'red';
}, []);
return <div ref={boxRef}>This text will be red</div>;
}
Conclusion
React hooks are powerful tools that simplify state and lifecycle management in functional components. With these hooks, you can create cleaner and more efficient React applications. Experiment with them in your projects to get a deeper understanding of their use cases.