TypeScript + React Hands-on
TypeScript provides complete type support for React development, improving code reliability.
Using TypeScript ensures that React components, Props, State, etc., all have complete type checking, reducing runtime errors.
View the React tutorial:https://www.example.com/vue3/react-tutorial.html
SVG Diagram: React + TypeScript Development Workflow
Why do you need to use TypeScript in React?
React component-based development produces a large amount of data flow such as Props, State, Context, etc.
Without type definitions, it is difficult to track the source and structure of data, and runtime errors are likely to occur.
TypeScript provides a complete type system for React: component Props have type checking, useState has type inference, and event handling has type hints.
Data flow:The data flow in React (Props, State, Context) needs type definitions, and TypeScript can ensure the type safety of the data flow.
Create a Project
Use a modern scaffolding tool to create a React project that supports TypeScript.
Initialize
npx create-react-app my-app --template typescript
# Or use Vite (recommended, faster)
npm create vite@latest my-app -- --template react-ts
Recommendation:Vite is currently the most recommended React build tool, with fast speed and a good development experience.
Component Types
Use the React.FC type to define function components.
src/components/Button.tsx
// Define the Props type for the button component
interface ButtonProps {
text: string; // Button text (required)
onClick: () => void; // Click callback (required)
disabled?: boolean; // Whether disabled (optional, default false)
variant?: "primary" | "secondary"; // Button variant (optional)
}
// Define the function component type using React.FC
const Button: React.FC<ButtonProps> = ({
text,
onClick,
disabled = false,
variant = "primary"
}) => {
return (
<button
className={`btn btn-${variant}`}
onClick={onClick}
disabled={disabled}
>
{text}
</button>
);
};
export default Button;
Running result:
Button 组件渲染成功
React.FC:This is the type of a React function component, including built-in types such as children, propTypes, etc.
Props Types
Define the Props interface of a component to pass data to child components.
src/components/UserCard.tsx
// Define the user type
interface User {
id: number; // User ID
name: string; // Username
email: string; // Email
avatar?: string; // Avatar (optional)
}
// Define the Props for the user card component
interface UserCardProps {
user: User; // User object (required)
onEdit: (user: User) => void; // Edit callback
onDelete: (id: number) => void; // Delete callback
}
const UserCard: React.FC<UserCardProps> = ({ user, onEdit, onDelete }) => {
return (
<div className="user-card">
{user.avatar && <img src={user.avatar} alt={user.name} />}
<h3>{user.name}</h3>
<p>{user.email}</p>
<button onClick={() => onEdit(user)}>Edit</button>
<button onClick={() => onDelete(user.id)}>Delete</button>
</div>
);
};
export default UserCard;
Type propagation:Pass types through Props to ensure consistent data types across the component tree.
useState Types
Provide type parameters for useState to ensure the correct state type.
src/components/Counter.tsx
const Counter: React.FC = () => {
// Basic type: explicitly specify the number type
const [count, setCount] = useState<number>(0);
// Object type: specify the object type
const [user, setUser] = useState<{ name: string; age: number }>({
name: "Alice",
age: 25
});
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(c => c + 1)}>+1</button>
<button onClick={() => setCount(c => c - 1)}>-1</button>
<p>User: {user.name}, {user.age}</p>
<button onClick={() => setUser({ ...user, age: user.age + 1 })}>
Age+1
</button>
</div>
);
};
export default Counter;
Running result:
Counter 组件渲染成功
Generic parameters:The T in useState<T> is the type of the state. If an initial value is provided, TypeScript can infer it automatically.
useEffect Types
useEffect also has complete type support.
src/components/DataFetcher.tsx
// Define the user type
interface User {
id: number;
name: string;
}
const DataFetcher: React.FC = () => {
// User list state
const [users, setUsers] = useState<User[]>([]);
// Loading state
const [loading, setLoading] = useState<boolean>(true);
// Error state
const [error, setError] = useState<string | null>(null);
useEffect(() => {
// Simulate fetching data
fetch("/api/users")
.then(res => res.json())
.then(data => {
setUsers(data);
setLoading(false);
})
.catch(err => {
setError(err.message);
setLoading(false);
});
}, []); // Empty dependency array: run only once when the component mounts
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>
);
};
export default DataFetcher;
Dependency array:The second parameter of useEffect is the dependency array. TypeScript will check whether all variables used in the callback have been declared in the array.
Event Handling
React events have dedicated type definitions.
src/components/Form.tsx
const Form: React.FC = () => {
// State of string type
const [name, setName] = useState<string>("");
// Form submission event handling
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault(); // Prevent the form's default submission
console.log("Submit:", name);
};
// Input change event handling
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setName(e.target.value);
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={name}
onChange={handleChange}
placeholder="Enter name"
/>
<button type="submit">Submit</button>
</form>
);
};
export default Form;
Running result:
Form 组件渲染成功
Event types:React provides types for every DOM event, such as FormEvent, ChangeEvent, MouseEvent, etc.
Notes
- React.FC:Recommended to use, to get complete type support
- Props interface:Define Props types for each component
- useState generics:Complex types need to be explicitly specified
- Event types:Use the event types provided by React
Best practices:Put type definitions and components in the same file, or centrally manage them in a types directory.
Summary
TypeScript greatly improves the React development experience.
- React.FC:Standard type for React function components
- Props:Use interface to define component props
- useState:Use generic parameters to specify the state type
- useEffect:Complete type support
- Events:Use React event types to avoid any
Other ExtensionsSuggestion:Use TypeScript directly in new projects, which can significantly reduce runtime errors.