**
What is a Hook?
**
Hooks were added to React in version 16.8. They allow function components to access state and other React features. Hooks allows us to "hook" into React features such as state and lifecycle methods.
In summary, Hooks are special functions that let function components use features that were only available in class components before React 16.8. Simply put, they let function components "do more" without needing a class.
For example:
import React, { useState } from 'react';
const Counter = () => {
//useState hook to manage count state
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increase</button>
</div>
);
};
export default Counter;
Explanation:
- useState(0) creates a state variable count starting at 0.
- setCount(count + 1) updates the count when the button is clicked.
- Every time the button is clicked, React re-renders the component with the new count.
This is a simple example of how hooks let function components manage state without needing a class component.
Hook Rules
There are 3 rules for hooks:
- Hooks can only be called inside React function components.
- Hooks can only be called at the top level of a component.
- Hooks cannot be conditional
Let's go into the different react hooks;
useState
The React useState Hook allows us to track state in a function component. state generally refers to data or properties that need to be tracked in an application. Just like in the example above, A simple counter that remembers the number when you click a button.
useEffect
This runs code when something changes. Think of it as a way to run code when your component loads or updates.
Example: Fetching data from an API when the page loads.
import React, { useState, useEffect } from 'react';
const FetchData = () => {
const [data, setData] = useState([]);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/posts')
.then((res) => res.json())
.then((data) => setData(data));
}, []); //runs only once when the component loads
return <p>Data Loaded: {data.length} items</p>;
};
export default FetchData;
Explanation
- useEffect(() => {...}, []) runs once when the component loads.
- It fetches data and stores it in state using setData(data).
- Without useEffect, this code would run every time the component updates, causing an infinite loop!
useContext
This is used to avoid passing props manually. This is a way to share data across components without passing props down manually.
Example: Managing a theme (dark/light mode) globally.
import React, { createContext, useContext } from 'react';
//create a Context for the theme
const ThemeContext = createContext('light');
const ThemedComponent = () => {
//access the theme value
const theme = useContext(ThemeContext);
return <p>Current theme: {theme}</p>;
};
const App = () => (
<ThemeContext.Provider value="dark">
<ThemedComponent />
</ThemeContext.Provider>
);
export default App;
Explanation
- createContext('light') creates a global state (default theme is "light").
- useContext(ThemeContext) allows any component to access the theme without prop drilling.
useRef
This keeps a value without re-rendering. Think of it as a way to store a value that React won’t forget but won’t trigger re-renders.
Example: Automatically focus on an input field when the page loads.
import React, { useRef, useEffect } from 'react';
const FocusInput = () => {
const inputRef = useRef(null);
useEffect(() => {
//focuses on the input when the page loads
inputRef.current.focus();
}, []);
return <input ref={inputRef} type="text" placeholder="Type here..." />;
};
export default FocusInput;
Explanation
- useRef(null) creates a reference to an input field.
- inputRef.current.focus() makes the input auto-focus when the page loads.
- Unlike useState, useRef does not trigger a re-render when updated
useMemo
This is used to improve performance.
Think of it as a way to "remember" a value so React doesn’t calculate it every time.
Example: Squaring a number without unnecessary recalculations.
import React, { useState, useMemo } from 'react';
const ExpensiveCalculation = ({ number }) => {
const squared = useMemo(() => {
console.log('Calculating square...');
return number * number;
}, [number]);
return <p>Squared: {squared}</p>;
};
Explanation
- useMemo(() => number * number, [number]) remembers the calculation and only updates if number changes.
- Without useMemo, React would re-calculate the square every render, which is inefficient.
useCallback
This prevents unnecessary re-creation of functions. It is used to prevent functions from being recreated when not needed.
Example: Preventing unnecessary re-renders in child components.
import React, { useState, useCallback } from 'react';
const Button = ({ handleClick }) => {
console.log('Button re-rendered');
return <button onClick={handleClick}>Click me</button>;
};
const Parent = () => {
const [count, setCount] = useState(0);
const memoizedHandleClick = useCallback(() => {
setCount((prev) => prev + 1);
}, []);
return (
<div>
<p>Count: {count}</p>
<Button handleClick={memoizedHandleClick} />
</div>
);
};
Explanation
- useCallback(() => {...}, []) stores the function so it doesn’t change unless dependencies change.
- Without useCallback, the button would re-render unnecessarily on every parent re-render
React also supports custom hooks which are reusable logic inside hooks. Instead of copying logic between components, you can create a custom hook and reuse it. They are commonly used for fetching data, managing authentication, or handling forms.
React Hooks make function components more powerful by letting us manage state, side effects, and performance optimizations without needing class components.
If you’re just starting, focus on useState for state management, useEffect for side effects like API calls, and useContext for sharing global data. As you grow, explore hooks like useRef, useMemo, and useReducer for better performance and complex logic.
Mastering hooks will help you write cleaner, more efficient React apps—so keep practicing and building!
Top comments (0)