Building Modern Web Applications with React and TypeScript
Introduction
In this post, I’ll share my experience and best practices for building modern web applications using React and TypeScript. We’ll cover everything from project setup to deployment.
Project Setup
First, let’s create a new project using Vite:
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install
Type-Safe Components
Here’s an example of a type-safe React component:
interface UserProfileProps {
name: string;
email: string;
role: 'admin' | 'user';
onUpdate: (id: string) => void;
}
const UserProfile: React.FC<UserProfileProps> = ({
name,
email,
role,
onUpdate
}) => {
return (
<div className="profile-card">
<h2>{name}</h2>
<p>{email}</p>
<span className={`role ${role}`}>{role}</span>
<button onClick={() => onUpdate(email)}>
Update Profile
</button>
</div>
);
};
Code Demo
Here’s a video demonstration of the concepts we’ve discussed:
Best Practices
- Always define proper interfaces for props
- Use strict TypeScript configuration
- Implement proper error boundaries
- Follow component composition patterns
Code Examples
Here’s how to implement a custom hook with TypeScript:
import { useState, useEffect } from 'react';
interface UseFetchResult<T> {
data: T | null;
loading: boolean;
error: Error | null;
}
function useFetch<T>(url: string): UseFetchResult<T> {
const [data, setData] = useState<T | null>(null);
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(url);
const json = await response.json();
setData(json);
} catch (err) {
setError(err instanceof Error ? err : new Error('An error occurred'));
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
return { data, loading, error };
}
Screenshots
Component hierarchy and data flow
TypeScript catching potential errors