Master error handling and loading UI in React. Learn to build resilient error boundaries and reusable skeletons for a polished, professional user experience.
Previously in this course, we explored integrating live data into the dashboard with react query. While fetching data efficiently is critical, a truly professional application must remain stable when things go wrong. Today, we’re leveling up our UX by implementing global error boundaries and reusable loading skeletons.
In production, your API will eventually fail, and your network will occasionally crawl. If your app simply crashes or shows a blank screen, you lose user trust. Robust error handling and thoughtful loading state management are not "extra" features; they are core requirements for a professional UI.
We want to move away from generic "Loading..." text and instead use visual placeholders that mimic the final layout. This reduces perceived wait times and keeps the user engaged. Simultaneously, we need to catch unexpected runtime errors before they unmount our entire component tree.
Standard try/catch blocks don't work for errors inside the React component lifecycle. For that, we use Error Boundaries—React components that catch JavaScript errors anywhere in their child component tree.
JSXimport React from CE9178">'react'; class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error) { return { hasError: true }; } componentDidCatch(error, errorInfo) { console.error("Dashboard Error:", error, errorInfo); } render() { if (this.state.hasError) { return ( <div className="error-fallback"> <h2>Something went wrong.</h2> <button onClick={() => window.location.reload()}>Retry</button> </div> ); } return this.props.children; } }
By wrapping our main dashboard components in this boundary, we ensure that a single failing widget doesn't crash the entire user session.
Instead of spinners, use skeletons to maintain the layout's structural integrity. Create a base component that provides the "shimmer" effect, then compose it into your dashboard modules.
JSXconst Skeleton = ({ width = "100%", height = "20px" }) => ( <div className="skeleton-pulse" style={{ width, height, borderRadius: CE9178">'4px', background: CE9178">'#e0e0e0' }} /> ); // Usage in a Dashboard Card const MetricSkeleton = () => ( <div className="card"> <Skeleton height="30px" width="60%" /> <Skeleton height="15px" width="40%" /> </div> );
When using React Query, you already have access to isError and isLoading states. Combine these with your UI components to provide feedback. As discussed in handling asynchronous state in react for wordpress plugins, it is vital to keep your state transitions predictable.
JSXconst DashboardWidget = () => { const { data, isLoading, isError } = useQuery({ queryKey: [CE9178">'metrics'], queryFn: fetchMetrics }); if (isLoading) return <MetricSkeleton />; if (isError) return <ErrorMessage message="Failed to load metrics." />; return <div>{data.value}</div>; };
Your task is to integrate these patterns into our running project:
ErrorBoundary.jsx file and wrap your main route content.SkeletonLoader component that matches the dimensions of your existing dashboard cards.useQuery calls to conditionally render the SkeletonLoader when isLoading is true.componentDidCatch method. If you just return null, you'll never know why your users are seeing your fallback UI.We’ve learned that error handling is about containment, while loading state management is about visual continuity. By utilizing React Error Boundaries and tailored skeleton loaders, you ensure your dashboard remains functional and polished, even when the underlying data layer experiences hiccups. These techniques bridge the gap between a prototype and a production-grade application.
Up next, we will explore controlled vs uncontrolled components to refine how we handle user input within our dashboard forms.
Master the asynchronous data lifecycle in React. Learn to implement robust loading, error, and success states to create a seamless, professional user experience.
Read moreLearn how to build a robust dashboard navigation UI by integrating sidebar layouts, private route guards, and authentication state in React.
Error Handling and Loading UI
Handling Multi-step Forms
Optimizing Form Submissions
Performance Profiling with React DevTools
Refactoring for Scalability
Finalizing Dashboard Data Flow
Deploying the Application
Advanced Hook Composition
Implementing Middleware for State
Advanced Context Patterns
Router Loaders and Data Prefetching
Complex Route Guards
Handling Large Datasets in UI
Testing Hooks and Components
Managing Global Modals
Implementing Keyboard Shortcuts
Optimizing Asset Loading
Internationalization Basics
Managing WebSocket Connections