React - Tooling & Architecture
Overview
Estimated time: 25–40 minutes
This guide covers pragmatic project structure, environment-driven configuration, consistency tooling (format/lint), and production-readiness checklists.
Learning Objectives
- Adopt a sensible, scalable folder structure (by feature).
- Provide configuration via context for environment differences.
- Know the essentials of formatting, linting, and basic CI checks.
- Use a deployment checklist to ship confidently.
Prerequisites
- Comfort with components, props/state, effects.
Try it: Config Context Pattern
View source
const { createContext, useContext, useState } = React;
const ConfigContext = createContext({ apiBase: '/api', flags: { search: true } });
function useConfig(){ return useContext(ConfigContext); }
function Panel(){
const cfg = useConfig();
return (
<div style={{border:'1px solid var(--border)', borderRadius:8, padding:8}}>
<div><strong>apiBase:</strong> {cfg.apiBase}</div>
<div><strong>flags.search:</strong> {String(cfg.flags.search)}</div>
</div>
);
}
function App(){
const dev = { apiBase:'/api-dev', flags:{ search:true } };
const prod = { apiBase:'/api', flags:{ search:true } };
const [mode, setMode] = useState('dev');
const cfg = mode==='dev' ? dev : prod;
return (
<ConfigContext.Provider value={cfg}>
<p>Environment: <strong>{mode}</strong></p>
<button onClick={() => setMode(m => m==='dev'?'prod':'dev')}>Toggle Env</button>
<div style={{marginTop:8}}><Panel /></div>
</ConfigContext.Provider>
);
}
ReactDOM.createRoot(document.getElementById('try-config')).render(<App />);
Recommended project structure (by feature)
src/
features/
todos/
components/
hooks/
api/
index.ts
users/
components/
hooks/
api/
shared/
components/
hooks/
api/
app/
routes/
providers/
App.tsx
Tooling
- Formatter: Prettier (consistent style).
- Linter: ESLint (bug catching + best practices).
- Basic CI: run format check, lint, and tests on push/PR.
Production readiness checklist
- Production React builds (minified) and sourcemaps for debugging.
- Error boundaries wrap critical trees; meaningful fallbacks.
- Accessibility checks (labels, keyboard focus, contrast).
- Performance sanity: memo where it matters; avoid re-render traps.
- Environment-driven config and feature flags.
- Basic monitoring/logging plan.
Syntax primer
- Config via Context:
createContext
+useContext
to avoid prop drilling.
Common pitfalls
- Global singletons for config make testing hard—prefer providers.
- Over-nesting providers; keep boundaries purposeful and documented.
Checks for Understanding
- When does a feature‑based folder structure help over layer‑based?
- Why use Context for config instead of globals?
Show answers
- It keeps related code together as features grow, aiding ownership and scaling.
- Context is testable, composable, and supports different configs per subtree.
Exercises
- Sketch your app’s feature folders and list shared modules.
- Add a config flag (e.g.,
enableBeta
) and read it in a component via Context. - Draft a minimal CI script that runs format, lint, and unit tests.