What are the 4 Hooks in React?
Four Essential Hooks in React
React Hooks are functions that let you use state and other React features in functional components. Introduced in React 16.8, Hooks have revolutionized how developers build and manage stateful logic in React applications. Here are the four fundamental Hooks that are widely used in React development:
1. useState
Purpose: Adds state management to functional components.
Description: The useState
Hook allows you to declare state variables in functional components. It returns a pair: the current state value and a function to update it.
Syntax:
const [state, setState] = useState(initialState);
Example:
import React, { useState } from 'react'; function Counter() { const [count, setCount] = useState(0); // Initialize count to 0 return ( <div> <p>Count: {count}</p> <button onClick={() => setCount(count + 1)}>Increment</button> </div> ); } export default Counter;
Key Points:
- Initial State: The argument passed to
useState
is the initial state. - State Updates: Use the setter function (
setCount
in the example) to update the state. It can accept a new state value or a function that receives the previous state.
2. useEffect
Purpose: Performs side effects in functional components.
Description: The useEffect
Hook lets you perform side effects such as data fetching, subscriptions, or manually changing the DOM. It serves the same purpose as lifecycle methods like componentDidMount
, componentDidUpdate
, and componentWillUnmount
in class components.
Syntax:
useEffect(() => { // Side effect code here return () => { // Cleanup code here (optional) }; }, [dependencies]);
Example:
import React, { useState, useEffect } from 'react'; import axios from 'axios'; function DataFetcher() { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { // Fetch data when the component mounts axios.get('/api/data') .then(response => { setData(response.data); setLoading(false); }) .catch(error => { console.error('Error fetching data:', error); setLoading(false); }); // Optional cleanup can be performed here return () => { // Cleanup code (e.g., canceling subscriptions) }; }, []); // Empty dependency array means this runs once on mount if (loading) return <p>Loading...</p>; return <div>Data: {JSON.stringify(data)}</div>; } export default DataFetcher;
Key Points:
- Dependencies: The dependency array determines when the effect runs. An empty array
[]
means the effect runs once after the initial render. Including variables makes the effect run whenever those variables change. - Cleanup Function: Returned function is used to clean up side effects, preventing memory leaks.
3. useContext
Purpose: Accesses context values without prop drilling.
Description: The useContext
Hook allows you to subscribe to React context without introducing nesting via context consumers. It simplifies the process of passing data through the component tree.
Syntax:
const value = useContext(MyContext);
Example:
import React, { useContext } from 'react'; const ThemeContext = React.createContext('light'); function ThemedButton() { const theme = useContext(ThemeContext); // Access the current theme return ( <button className={theme}> I am styled by theme context! </button> ); } function App() { return ( <ThemeContext.Provider value="dark"> <ThemedButton /> </ThemeContext.Provider> ); } export default App;
Key Points:
- Context Creation: Use
React.createContext
to create a context. - Provider: Wrap components with the context provider to supply context values.
- Consumption: Use
useContext
within any component to access the current context value.
4. useReducer
Purpose: Manages complex state logic in functional components.
Description: The useReducer
Hook is an alternative to useState
for managing more complex state logic. It is especially useful when state transitions depend on previous states or when managing multiple related state variables.
Syntax:
const [state, dispatch] = useReducer(reducer, initialState);
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' })}>+</button> <button onClick={() => dispatch({ type: 'decrement' })}>-</button> </div> ); } export default Counter;
Key Points:
- Reducer Function: A pure function that takes the current state and an action, then returns a new state.
- Dispatch: A function to send actions to the reducer.
- State Management: Suitable for scenarios with multiple state variables or complex state transitions.
Additional Important Hooks
While the above four Hooks are fundamental, React provides several other built-in Hooks that enhance functionality:
useRef
: Accesses DOM nodes or persists mutable values across renders without causing re-renders.useMemo
: Memoizes expensive computations to optimize performance.useCallback
: Memoizes callback functions to prevent unnecessary re-creations.useLayoutEffect
: Similar touseEffect
but fires synchronously after all DOM mutations.useImperativeHandle
: Customizes the instance value exposed when usingref
.useDebugValue
: Displays a label for custom Hooks in React DevTools.
Conclusion
React Hooks have transformed the way developers build and manage stateful logic in React applications. The four essential Hooks—useState
, useEffect
, useContext
, and useReducer
—provide powerful tools for handling state, side effects, context, and complex state logic within functional components. Mastering these Hooks is crucial for building efficient, maintainable, and scalable React applications. Additionally, exploring other built-in Hooks can further enhance your ability to create sophisticated and optimized user interfaces.
GET YOUR FREE
Coding Questions Catalog