React Hooks allow you to use state and other React features without writing a class. Here are some of the most commonly used hooks:
The useState
hook lets you track state changes in your functional components. It returns a state variable and a function to update it.
Example: A simple counter component.
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
You clicked {count} times
);
}
The useEffect
hook runs code after render and can be used to perform side effects in functional components, such as fetching data, subscribing to events, or manually manipulating the DOM.
Example: Fetching data from an API.
import React, { useState, useEffect } from 'react';
function DataFetcher() {
const [data, setData] = useState([]);
useEffect(() => {
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => setData(data));
}, []); // Empty dependency array means this effect runs once
return (
{data.map(item => (
- {item.name}
))}
);
}
The useContext
hook accesses context data, allowing you to share values between components without having to pass props down manually.
Example: Using a theme context in your components.
import React, { createContext, useContext, useState } from 'react';
const ThemeContext = createContext();
function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
return (
{children}
);
}
function ThemedComponent() {
const { theme, setTheme } = useContext(ThemeContext);
return (
Current theme: {theme}
);
}
The useReducer
hook is used to manage complex state logic, especially when the state involves multiple sub-values or when the next state depends on the previous one.
Example: Managing complex state logic in a counter application.
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 (
Count: {state.count}
);
}
The useCallback
hook caches functions, ensuring that they are only recreated if the dependencies change. This helps to optimize performance, especially when passing functions as props to child components.
Example: Caching a function to prevent unnecessary re-creation.
import React, { useState, useCallback } from 'react';
function Button({ handleClick }) {
return ;
}
function ParentComponent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
setCount((prevCount) => prevCount + 1);
}, []);
return (
Count: {count}
);
}
The useMemo
hook caches values, preventing expensive calculations on every render. It's useful for optimizing performance.
Example: Memoizing a computed value to avoid recalculations.
import React, { useMemo, useState } from 'react';
function ExpensiveComponent({ data }) {
const computedValue = useMemo(() => {
// Expensive calculation
return data.reduce((acc, curr) => acc + curr, 0);
}, [data]);
return Computed Value: {computedValue};
}
The useRef
hook is used for referencing DOM elements or storing mutable values that persist across renders without causing a re-render.
Example: Focusing an input element.
import React, { useRef } from 'react';
function FocusInput() {
const inputRef = useRef(null);
const focusInput = () => {
inputRef.current.focus();
};
return (
);
}