← Back to Chapters

Advanced React Concepts

⚛️ Advanced React Concepts

? Quick Overview

Advanced React concepts help you build scalable, maintainable, and high-performance applications once you are comfortable with components, hooks, state, and props.

? Key Concepts

  • Higher-Order Components (HOC)
  • Render Props
  • Portals
  • Error Boundaries
  • Code Splitting & Lazy Loading
  • Memoization & Performance Optimization
  • Custom Hooks

? Higher-Order Components

A Higher-Order Component is a function that takes a component and returns an enhanced version of it.

? View Code Example
// HOC that logs props before rendering
function withLogger(WrappedComponent) {
return function EnhancedComponent(props) {
console.log("Props received:", props);
return <WrappedComponent {...props} />;
};
}

function Hello({ name }) {
return <h3>Hello, {name}</h3>;
}

export default withLogger(Hello);

? Render Props

Render props share logic by passing a function that controls what gets rendered.

? View Code Example
// Component exposing mouse position via render prop
function MouseTracker({ render }) {
const [pos, setPos] = React.useState({ x: 0, y: 0 });

return (
<div onMouseMove={e => setPos({ x: e.clientX, y: e.clientY })}>
{render(pos)}
</div>
);
}

? Portals

Portals allow rendering outside the parent DOM hierarchy.

? View Code Example
// Portal rendering content into modal-root
import { createPortal } from "react-dom";

function Modal({ children }) {
return createPortal(children, document.getElementById("modal-root"));
}

⚠️ Error Boundaries

Error boundaries catch runtime errors and prevent the app from crashing.

? View Code Example
// Class component used as error boundary
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}

static getDerivedStateFromError() {
return { hasError: true };
}

render() {
if (this.state.hasError) {
return <h3>Something went wrong</h3>;
}
return this.props.children;
}
}

⚙️ Code Splitting & Lazy Loading

Lazy loading loads components only when required.

? View Code Example
// Lazy loading component with Suspense
const Dashboard = React.lazy(() => import("./Dashboard"));

function App() {
return (
<React.Suspense fallback={<p>Loading...</p>}>
<Dashboard />
</React.Suspense>
);
}

⚡ Memoization & Performance

Memoization avoids unnecessary re-renders.

? View Code Example
// Memoized component to improve performance
const Expensive = React.memo(({ value }) => {
return <div>Value: {value}</div>;
});

? Custom Hooks

Custom hooks reuse logic across components.

? View Code Example
// Custom hook for window width
function useWindowWidth() {
const [width, setWidth] = React.useState(window.innerWidth);

React.useEffect(() => {
const onResize = () => setWidth(window.innerWidth);
window.addEventListener("resize", onResize);
return () => window.removeEventListener("resize", onResize);
}, []);

return width;
}

? Tips & Best Practices

  • Use memoization only where performance issues exist
  • Wrap major sections with error boundaries
  • Prefer custom hooks over duplicated logic
  • Combine lazy loading with routing

? Try It Yourself

  1. Create a logging HOC
  2. Build a custom mouse tracking hook
  3. Add lazy loading to routes
  4. Wrap components using an error boundary