**FETCH API - POINTS**
```
import { useState, useEffect } from "react";
import axios from "axios";
/**
* Custom Hook: useFetch
*
* This hook fetches data from an API endpoint and returns the response data, loading status, and errors.
* It ensures that the data fetch happens only when needed and updates reactively based on dependencies.
*/
const useFetch = (url) => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await axios.get(url);
setData(response.data);
} catch (err) {
setError(err);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
return { data, loading, error };
};
export default useFetch;
```
**PROTECTED ROUTES TO PAGES:**
```
import { Navigate, Outlet } from "react-router-dom";
/**
* ProtectedRoute Component
*
* This component prevents users from accessing certain routes unless they are authenticated.
* If a user is logged in, the children components (nested routes) will be rendered.
* Otherwise, they will be redirected to the login page.
*/
const ProtectedRoute = ({ user }) => {
return user ? <Outlet /> : <Navigate to="/login" />;
};
export default ProtectedRoute;
```
**PERFORMANCE - DOES NOT LOAD UNLESS NEEDED**
```
import { lazy, Suspense } from "react";
/**
* Lazy-loaded Components
*
* Instead of importing components normally, we use React's lazy function to load them only when needed.
* The Suspense component ensures a fallback UI (like a loading spinner) while the component loads.
*/
const Dashboard = lazy(() => import("./Dashboard"));
const Settings = lazy(() => import("./Settings"));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<Dashboard />
<Settings />
</Suspense>
);
}
export default App;
```
**GLOBAL STATE MANAGEMENT:**
```
import { createContext, useContext, useState } from "react";
/**
* AuthContext
*
* This context provides authentication state and functions globally across the app.
* Instead of passing props manually to different components, we use the `useContext` hook for easy access.
*/
const AuthContext = createContext();
export const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
const login = (userData) => setUser(userData);
const logout = () => setUser(null);
return (
<AuthContext.Provider value={{ user, login, logout }}>
{children}
</AuthContext.Provider>
);
};
// Custom Hook to use AuthContext
export const useAuth = () => useContext(AuthContext);
```
**PREVENT EXCESSIVE API CALLS:**
```
import { useState, useEffect } from "react";
/**
* useDebounce Hook
*
* This hook delays execution of a function until after a specified delay time has passed.
* Useful for search inputs where we don't want to call the API on every keystroke.
*/
const useDebounce = (value, delay) => {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => clearTimeout(handler);
}, [value, delay]);
return debouncedValue;
};
export default useDebounce;
```
**WEB SOCKET:**
```
import { useEffect, useState } from "react";
import io from "socket.io-client";
const socket = io("http://localhost:5000");
/**
* useSocket Hook
*
* This hook connects to a WebSocket server and listens for messages in real-time.
* It updates the UI whenever new data is received.
*/
const useSocket = (event) => {
const [data, setData] = useState(null);
useEffect(() => {
socket.on(event, (message) => setData(message));
return () => socket.off(event);
}, [event]);
return data;
};
export default useSocket;
```
**ERROR BOUNDARY HANDLING:**
```
import { Component } from "react";
/**
* ErrorBoundary Component
*
* This component catches JavaScript errors in any child component tree and displays a fallback UI instead of crashing the entire app.
* Useful for preventing white screens due to unexpected errors.
*/
class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError() {
return { hasError: true };
}
componentDidCatch(error, info) {
console.error("Error caught in boundary:", error, info);
}
render() {
if (this.state.hasError) {
return <h2>Something went wrong.</h2>;
}
return this.props.children;
}
}
export default ErrorBoundary;
```
**DARK/LIGHT MODE:**
```
import { useState, useEffect } from "react";
/**
* useDarkMode Hook
*
* This hook enables a dark mode toggle and saves the preference in local storage.
* It updates the theme dynamically based on user selection.
*/
const useDarkMode = () => {
const [darkMode, setDarkMode] = useState(() => {
return localStorage.getItem("darkMode") === "true";
});
useEffect(() => {
if (darkMode) {
document.documentElement.classList.add("dark");
} else {
document.documentElement.classList.remove("dark");
}
localStorage.setItem("darkMode", darkMode);
}, [darkMode]);
return [darkMode, setDarkMode];
};
export default useDarkMode;
```