🎓 Top 15 Udemy Courses (80-90% Discount): My Udemy Courses - Ramesh Fadatare — All my Udemy courses are real-time and project oriented courses.
▶️ Subscribe to My YouTube Channel (178K+ subscribers): Java Guides on YouTube
▶️ For AI, ChatGPT, Web, Tech, and Generative AI, subscribe to another channel: Ramesh Fadatare on YouTube
In this article, we’ll explore the top 10 mistakes in React.js and how to avoid them with best practices and code examples.
1️⃣ Mutating State Directly Instead of Using setState()
❌ Mistake: Modifying State Directly
const [count, setCount] = useState(0);
const increment = () => {
count += 1; // ❌ Directly modifying state
};
✔ Issue:
- React does not detect the state change, so the component does not re-render.
✅ Solution: Use setState() to Update State Properly
const [count, setCount] = useState(0);
const increment = () => {
setCount(prevCount => prevCount + 1); // ✅ Correct way
};
✔ Benefit: Ensures React re-renders the component properly.
2️⃣ Using index as a Key in Lists
❌ Mistake: Using Array Index as Key
{items.map((item, index) => (
<li key={index}>{item.name}</li> // ❌ Bad practice
))}
✔ Issue:
- If items are reordered, React cannot track changes properly, leading to unexpected UI behavior.
✅ Solution: Use a Unique Identifier as a Key
{items.map(item => (
<li key={item.id}>{item.name}</li> // ✅ Correct way
))}
✔ Benefit: Prevents unnecessary re-renders and ensures better list tracking.
3️⃣ Overusing State Instead of Using Props or Context API
❌ Mistake: Managing Global Data in Local State
const [theme, setTheme] = useState("light"); // ❌ Managing global theme locally
✔ Issue:
- Makes it difficult to share data across multiple components.
✅ Solution: Use Context API for Global State
const ThemeContext = createContext();
const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState("light");
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
};
✔ Benefit: Makes data sharing across components easier.
4️⃣ Not Using useEffect Dependencies Properly
❌ Mistake: Forgetting the Dependency Array
useEffect(() => {
console.log("Component Mounted!");
}); // ❌ Will run on every render
✔ Issue:
- This runs on every render, causing performance issues.
✅ Solution: Provide Dependency Array
useEffect(() => {
console.log("Component Mounted!");
}, []); // ✅ Runs only once
✔ Benefit: Avoids unnecessary re-executions, improving performance.
5️⃣ Overusing useEffect for State Changes
❌ Mistake: Updating State Inside useEffect Without a Condition
useEffect(() => {
setData(fetchData()); // ❌ Infinite loop risk
}, [data]);
✔ Issue:
- This can cause an infinite loop if not handled properly.
✅ Solution: Use Conditions or Memoization
useEffect(() => {
setData(fetchData());
}, []); // ✅ Runs only once
✔ Benefit: Prevents unnecessary re-renders and infinite loops.
6️⃣ Not Memoizing Expensive Calculations (useMemo)
❌ Mistake: Performing Expensive Calculations in Render
const result = heavyCalculation(data); // ❌ Runs on every render
✔ Issue:
- Recalculates on every render, causing performance issues.
✅ Solution: Use useMemo() to Optimize Performance
const result = useMemo(() => heavyCalculation(data), [data]); // ✅ Optimized
✔ Benefit: Caches the result, reducing unnecessary computations.
7️⃣ Using useEffect Instead of useMemo or useCallback
❌ Mistake: Using useEffect for Derived State
const [filteredItems, setFilteredItems] = useState([]);
useEffect(() => {
setFilteredItems(items.filter(item => item.active));
}, [items]); // ❌ Unnecessary state updates
✔ Issue:
- Triggers unnecessary re-renders.
✅ Solution: Use useMemo Instead
const filteredItems = useMemo(() => items.filter(item => item.active), [items]); // ✅ Optimized
✔ Benefit: Prevents unnecessary state updates.
8️⃣ Forgetting to Cleanup Effects in useEffect
❌ Mistake: Not Cleaning Up Event Listeners
useEffect(() => {
window.addEventListener("resize", handleResize);
}, []); // ❌ Event listener never removed
✔ Issue:
- Leads to memory leaks.
✅ Solution: Cleanup with Return Function
useEffect(() => {
const handleResize = () => console.log("Resized!");
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize); // ✅ Cleanup
};
}, []);
✔ Benefit: Prevents memory leaks and ensures proper event handling.
9️⃣ Using Anonymous Functions in useEffect Dependencies
❌ Mistake: Passing Functions Directly as Dependencies
useEffect(() => {
fetchData();
}, [fetchData]); // ❌ Triggers effect on every render
✔ Issue:
- Creates a new function reference on every render, triggering useEffect unnecessarily.
✅ Solution: Use useCallback to Memoize Functions
const fetchData = useCallback(() => {
// API call
}, []);
useEffect(() => {
fetchData();
}, [fetchData]); // ✅ Function reference remains stable
✔ Benefit: Prevents unnecessary effect executions.
🔟 Not Lazy Loading Components (React.lazy())
❌ Mistake: Importing All Components at Once
import Dashboard from "./Dashboard";
import Profile from "./Profile";
✔ Issue:
- Increases initial page load time.
✅ Solution: Use Lazy Loading for Performance Optimization
const Dashboard = React.lazy(() => import("./Dashboard"));
const Profile = React.lazy(() => import("./Profile"));
<Suspense fallback={<div>Loading...</div>}>
<Dashboard />
</Suspense>
✔ Benefit: Improves page speed by loading components only when needed.
🎯 Conclusion
React is powerful but also tricky to master. By avoiding these common mistakes, you can build faster, scalable, and maintainable applications.
✔ Use setState() instead of modifying state directly
✔ Avoid using array index as keys in lists
✔ Use Context API instead of unnecessary local state
✔ Optimize performance with useMemo and useCallback
✔ Ensure proper effect cleanup in useEffect
✔ Use lazy loading for better performance
By following these best practices, you’ll write better React code and build high-performing applications! 🚀
Comments
Post a Comment
Leave Comment