Building Real Applications
Project Structure
Organize your React app effectively:
src/
components/
Header.jsx
Footer.jsx
pages/
Home.jsx
About.jsx
hooks/
useAuth.js
utils/
api.js
App.jsx
index.js
API Integration
Fetch data from APIs:
function UserList() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch('/api/users')
.then(res => res.json())
.then(data => {
setUsers(data);
setLoading(false);
})
.catch(err => {
setError(err.message);
setLoading(false);
});
}, []);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
Routing with React Router
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/users/:id" element={<UserProfile />} />
</Routes>
</BrowserRouter>
);
}
Form Validation
function SignupForm() {
const [formData, setFormData] = useState({
email: '',
password: ''
});
const [errors, setErrors] = useState({});
function validate() {
const newErrors = {};
if (!formData.email.includes('@')) {
newErrors.email = 'Invalid email';
}
if (formData.password.length < 8) {
newErrors.password = 'Password too short';
}
return newErrors;
}
function handleSubmit(e) {
e.preventDefault();
const newErrors = validate();
if (Object.keys(newErrors).length === 0) {
// Submit form
} else {
setErrors(newErrors);
}
}
return (
<form onSubmit={handleSubmit}>
<input
type="email"
value={formData.email}
onChange={e => setFormData({...formData, email: e.target.value})}
/>
{errors.email && <span>{errors.email}</span>}
<input
type="password"
value={formData.password}
onChange={e => setFormData({...formData, password: e.target.value})}
/>
{errors.password && <span>{errors.password}</span>}
<button type="submit">Sign Up</button>
</form>
);
}
Error Boundaries
class ErrorBoundary extends React.Component {
state = { hasError: false };
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, info) {
console.log(error, info);
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
// Usage
<ErrorBoundary>
<MyApp />
</ErrorBoundary>
Deployment
Deploy your React app:
# Build for production
npm run build
# Deploy to Vercel
npx vercel
# Deploy to Netlify
npm run build && netlify deploy