Advanced React concepts help you build scalable, maintainable, and high-performance applications once you are comfortable with components, hooks, state, and props.
A Higher-Order Component is a function that takes a component and returns an enhanced version of it.
// 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 share logic by passing a function that controls what gets rendered.
// 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 allow rendering outside the parent DOM hierarchy.
// Portal rendering content into modal-root
import { createPortal } from "react-dom";
function Modal({ children }) {
return createPortal(children, document.getElementById("modal-root"));
}
Error boundaries catch runtime errors and prevent the app from crashing.
// 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;
}
}
Lazy loading loads components only when required.
// Lazy loading component with Suspense
const Dashboard = React.lazy(() => import("./Dashboard"));
function App() {
return (
<React.Suspense fallback={<p>Loading...</p>}>
<Dashboard />
</React.Suspense>
);
}
Memoization avoids unnecessary re-renders.
// Memoized component to improve performance
const Expensive = React.memo(({ value }) => {
return <div>Value: {value}</div>;
});
Custom hooks reuse logic across components.
// 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;
}