跪拜 Guibai
← All articles
JavaScript · Frontend · Backend

Stop Waiting on Backend APIs: A Seven-File React Pattern for Independent Frontend Development

By mONESY ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Frontend teams blocked by unavailable or unstable backend APIs lose days of velocity. This pattern eliminates that dependency during development, letting UI work, state management, and interaction logic ship in parallel with backend work. The one-line switch from mock to real endpoints also removes the risk of scattered hardcoded URLs that break during integration.

Summary

A seven-file React architecture isolates all backend coupling into a dedicated API layer, letting frontend teams build complete interfaces without waiting for real endpoints. A centralized axios instance in `api/config.js` sets a `baseURL` that points to a local mock server during development. Page components call abstracted functions like `getTodos()` from `api/todos.js` and never touch URLs or HTTP clients directly. A Vite plugin intercepts requests matching the mock definitions and returns hardcoded responses, so the full data flow runs end-to-end before any backend code exists. Switching to a real server requires changing exactly one line in `config.js`. The pattern also demonstrates React Router lazy loading with `lazy()` and `Suspense`, keeping initial bundle sizes small by loading page code only on navigation.

Takeaways
All backend coupling lives in `api/config.js` and `api/todos.js`; page components never import axios or touch URLs directly.
`axios.create()` with a `baseURL` lets every request share a common prefix, so switching from mock to production changes one line.
A Vite mock plugin intercepts requests matching `/api/todos` and returns hardcoded JSON, simulating a real server with configurable latency.
React Router's `lazy()` and `Suspense` split page bundles so code for unvisited routes never loads on the initial screen.
Using `<Link>` instead of `<a>` prevents full-page reloads and preserves SPA state during navigation.
An IIFE inside `useEffect` works around the restriction that the effect callback cannot itself be `async`.
Conclusions

The pattern's real value is not the mock server but the API abstraction layer: page components call `getTodos()` with no knowledge of HTTP, URLs, or whether data is real, which is what makes the mock-to-production switch trivial.

Many teams add mock servers as an afterthought, but placing the mock definition file and the API config in the same directory structure as the real API modules makes the switch a configuration change rather than a code rewrite.

The article leaves `Suspense` without a `fallback`, which is a common half-implementation of lazy loading that works until a slow network reveals a blank screen where a loading indicator should be.

Concepts & terms
API abstraction layer
A set of modules that wrap HTTP calls behind named functions (e.g., `getTodos()`), so page components never import axios, fetch, or hardcode URLs. Changing the data source requires editing only the abstraction layer.
Vite mock plugin (vite-plugin-mock)
A Vite dev-server plugin that intercepts HTTP requests matching configured URL patterns and returns hardcoded responses from local files, simulating a backend without running one.
React lazy loading
Using `React.lazy()` with dynamic `import()` to split a component into a separate JavaScript bundle that loads only when the component is first rendered, reducing initial page load size.
IIFE (Immediately Invoked Function Expression)
A function defined and called immediately: `(async () => { ... })()`. Used inside `useEffect` to run async logic because the effect callback itself cannot be declared `async`.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗