React is a widely-used JavaScript library for building dynamic web applications. Since its open-source release by Facebook, React has gained immense popularity and is now used by major websites such as:
Apple.com, Cloudflare.com, LinkedIn.com, Amazon.com, Samsung.com, Yandex.com, Alibaba.com, AliExpress.com
Hooks revolutionized React by allowing functional components to access state and other React features without using classes. They provide a more intuitive API for managing props, state, context, refs, and lifecycle methods.
1. useState: The Foundation of State Management
The useState hook is the most basic yet most essential hook in React. it allows you to add local state to functional components, which was previously only possible in class components.
How it Works
When you call useState, it returns an array with two elements:
- The current state value.
- A function to update that state.
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div className="counter-container">
<h3>Count: {count}</h3>
<button onClick={() => setCount(count + 1)}>Increment</button>
<button onClick={() => setCount(count - 1)}>Decrement</button>
</div>
);
}
Pro Tip: Functional Updates
If your new state depends on the previous state, always use a functional update to avoid stale closure issues:
setCount(prevCount => prevCount + 1);
2. useEffect: Managing Side Effects
Side effects include anything that happens “outside” of the component’s render cycle, such as data fetching, subscriptions, or manually changing the DOM.
The Dependency Array
The most important part of useEffect is the second argument: the dependency array.
- No array: Runs after every render.
- Empty array
[]: Runs only once (when the component mounts). - With dependencies
[props, state]: Runs only when those specific values change.
useEffect(() => {
const fetchData = async () => {
const response = await fetch('https://api.example.com/data');
const result = await response.json();
setData(result);
};
fetchData();
}, []); // Empty array means this runs once on mount
Cleanup Function
If your effect creates a subscription or timer, always return a cleanup function to prevent memory leaks:
useEffect(() => {
const timer = setInterval(() => {
console.log('Tick');
}, 1000);
return () => clearInterval(timer); // Cleanup on unmount
}, []);
3. useMemo: Optimizing Expensive Calculations
Performance optimization is key in large React apps. useMemo allows you to “memoize” (cache) the result of a computation so it only recalculates when its dependencies change.
When to use useMemo?
Use it when you have a function that performs heavy calculations that don’t need to run on every render.
const expensiveCalculation = (num) => {
console.log('Calculating...');
for (let i = 0; i < 1000000000; i++) {} // Artificial delay
return num * 2;
};
function App({ number }) {
const memoizedValue = useMemo(() => expensiveCalculation(number), [number]);
return <div>Result: {memoizedValue}</div>;
}
Note: Don’t overuse useMemo. The hook itself has a small performance cost. Only apply it if you’re actually seeing performance drops.
4. useCallback: Stabilizing Function References
While useMemo caches a value, useCallback caches a function instance.
Why is this useful?
In React, functions are recreated on every render. If you pass a function as a prop to a child component that uses React.memo, that child will re-render every time because the function reference has changed. useCallback prevents this.
const handleIncrement = useCallback(() => {
setCount(c => c + 1);
}, []); // Function reference stays the same
By wrapping your event handlers in useCallback, you ensure that child components don’t re-render unnecessarily, making your app feel much snappier.
Summary Checklist
| Hook | Best Used For | Key Behavior |
|---|---|---|
| useState | Local state | Triggers a re-render when updated. |
| useEffect | Side effects | Runs after render; supports cleanup. |
| useMemo | Calculated values | Returns a cached value. |
| useCallback | Functions | Returns a stable function reference. |
Conclusion
Mastering these four hooks is the first step toward React excellence. By combining useState for logic, useEffect for integration, and useMemo/useCallback for performance, you’ll be able to build robust and efficient modern web applications.
Ready to take your React skills to the next level? Start experimenting with these hooks in your next project!
Frequently Asked Questions (FAQ)
Q: Can I use hooks inside a loop?
A: No. Hooks must always be called at the top level of your React function components to ensure they are called in the same order every time.
Q: Is useEffect better than lifecycle methods?
A: useEffect provides a more unified way to handle logic that was previously spread across componentDidMount, componentDidUpdate, and componentWillUnmount.
Q: Should I use useMemo for every object?
A: No. Only use it when referential equality is important for downstream components or when the object creation is truly expensive.
Member discussion
0 commentsStart the conversation
Become a member of >hacksubset_ to start commenting.
Already a member? Sign in