Loading and error states help manage user expectations during data fetching or processing. Properly implemented, they prevent unnecessary re-renders and reduce CPU usage by avoiding repeated failed requests. However, excessive or complex animations in loading indicators can reduce frame rates below the smooth 60fps target, causing janky UI. Memory impact is minimal if states are simple, but large error images or heavy animations can increase memory use and battery drain.
Loading and error states in React Native - Build, Publish & Deploy
- Use lightweight, simple loading indicators like spinners or skeleton placeholders instead of heavy animations.
- Cache data to avoid repeated loading states on the same content.
- Debounce or throttle network requests to prevent multiple simultaneous loads.
- Use React Native's
useMemoorReact.memoto avoid unnecessary re-renders of loading/error components. - Show error messages only when necessary and keep UI minimal to maintain 60fps.
Loading and error states themselves add negligible size to the app bundle if implemented with native components and simple styles. Avoid importing large third-party animation libraries just for loading indicators, as they can increase bundle size significantly and slow startup time. Using built-in React Native components and minimal assets keeps the app lightweight and fast to launch.
Both platforms support similar loading and error UI patterns, but native components differ slightly. iOS uses ActivityIndicator with a default spinner style, while Android's spinner may look different. Error messages should follow platform conventions: iOS favors subtle alerts, Android uses snackbars or toasts. Also, Android devices vary more in performance, so keep loading states lightweight to maintain smooth UI across devices.
- Apple App Store requires apps to handle loading and error states gracefully to avoid crashes or frozen screens (Apple Human Interface Guidelines).
- Google Play expects apps to provide clear feedback during loading and errors to prevent user confusion (Material Design guidelines).
- Both stores reject apps that appear unresponsive or crash due to unhandled errors.
- Ensure error messages do not expose sensitive information or internal error codes.
Your app takes 5 seconds to load this screen. What's likely wrong?
- Network requests are not optimized or retried properly, causing delays.
- Loading indicators use heavy animations slowing down rendering.
- Data fetching is blocking the main thread, freezing UI.
- Error states are not handled, causing repeated failed loads.
Practice
Solution
Step 1: Understand loading state role
Loading states inform users that the app is busy fetching or processing data.Step 2: Differentiate from error state
Error states show problems, not loading progress.Final Answer:
To show the user that data is being fetched or processed -> Option BQuick Check:
Loading state = show progress [OK]
- Confusing loading with error states
- Thinking loading hides content permanently
- Assuming loading restarts the app
Solution
Step 1: Recall useState syntax
useState returns an array with current value and setter function, usually destructured.Step 2: Check options for correct destructuring
const [loading, setLoading] = useState(false); correctly uses array destructuring with const and initial value false.Final Answer:
const [loading, setLoading] = useState(false); -> Option DQuick Check:
useState destructuring = const [loading, setLoading] = useState(false); [OK]
- Not destructuring the array from useState
- Using let or var instead of const
- Assigning useState directly to a variable without destructuring
loading is true?const [loading, setLoading] = useState(true); return ( loading ? Loading... : Data loaded );
Solution
Step 1: Check the value of loading
loading is true initially.Step 2: Evaluate the ternary expression
If loading is true, Loading... is returned and shown.Final Answer:
Loading... -> Option AQuick Check:
loading true shows loading text [OK]
- Confusing true and false branches
- Thinking nothing shows when loading is true
- Assuming error message shows automatically
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
if (loading) {
return Loading...;
} else if (error) {
return Error occurred;
}
return Data loaded;Solution
Step 1: Check initial loading state
Loading is false initially, so loading screen never shows on start.Step 2: Understand typical loading flow
Loading should start as true while fetching data, then false after.Final Answer:
Loading state should be true initially to show loading -> Option CQuick Check:
Initial loading true needed to show loading [OK]
- Setting loading false initially hides loading screen
- Thinking error must be boolean
- Assuming if-else order is wrong
Solution
Step 1: Understand state separation
Separate states for loading, error, and data allow clear control of UI for each condition.Step 2: Evaluate options
Use separate states: loading (boolean), error (string|null), data (object|null), and conditionally render based on these uses best practice: boolean loading, error message or null, and data object or null.Final Answer:
Use separate states: loading (boolean), error (string|null), data (object|null), and conditionally render based on these -> Option AQuick Check:
Separate states for clarity and control [OK]
- Ignoring error handling
- Using one string state for all conditions
- Rendering data without waiting for fetch
Ready to prove it?
Pass the test and this pattern moves unknown
