.
Basic component that displays a greeting message. This will illustrate the use of basic types and interfaces for component props.
import React from 'react';
interface GreetingProps {
name: string;
isLoggedIn: boolean;
}
const Greeting: React.FC<GreetingProps> = ({ name, isLoggedIn }) => {
return (
<div>
{isLoggedIn ? <h1>Hello, {name}!</h1> : <h1>Welcome, Guest!</h1>}
</div>
);
};
export default Greeting;
useState
with generics to ensure type safety in state management:
import React, { useState } from 'react';
interface User {
id: number;
name: string;
}
const UserProfile: React.FC = () => {
// Using generics to define the type of state
const [user, setUser] = useState<User | null>(null);
const login = () => {
// Simulate a login
setUser({ id: 1, name: 'John Doe' });
};
const logout = () => {
setUser(null);
};
return (
<div>
{user ? (
<div>
<h1>Welcome back, {user.name}!</h1>
<button onClick={logout}>Logout</button>
</div>
) : (
<button onClick={login}>Login</button>
)}
</div>
);
};
export default UserProfile;
Typing props in a function component using TypeScript. Button
component that takes a few props:
import React from 'react';
interface ButtonProps {
label: string;
onClick: () => void; // Define the onClick as a function that returns nothing
type?: 'button' | 'submit' | 'reset'; // Optional prop with default type
}
const Button: React.FC<ButtonProps> = ({ label, onClick, type = 'button' }) => {
return (
<button type={type} onClick={onClick}>
{label}
</button>
);
};
export default Button;
TypeScript with React's useEffect
and useState
hooks to manage and display a list of items:
import React, { useState, useEffect } from 'react';
interface Item {
id: number;
name: string;
}
const ItemList: React.FC = () => {
const [items, setItems] = useState<Item[]>([]); // An array of Item objects
useEffect(() => {
// Simulate fetching data
const fetchedItems: Item[] = [
{ id: 1, name: 'Apple' },
{ id: 2, name: 'Banana' }
];
setItems(fetchedItems);
}, []); // Dependency array is empty, so this runs once on mount
return (
<ul>
{items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
};
export default ItemList;
Handling events like form submissions or input changes can benefit greatly from TypeScript's ability to define the types of event objects:
import React, { useState } from 'react';
const EmailSignup: React.FC = () => {
const [email, setEmail] = useState('');
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setEmail(event.target.value);
};
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
alert(`Signup for ${email}`);
};
return (
<form onSubmit={handleSubmit}>
<label>
Email:
<input type="email" value={email} onChange={handleChange} />
</label>
<button type="submit">Sign Up</button>
</form>
);
};
export default EmailSignup;
In this example, React.ChangeEvent<HTMLInputElement>
and React.FormEvent<HTMLFormElement>
are used to type the event parameters, ensuring you have access to all appropriate properties and methods related to those events.
Example: use the React Context API with TypeScript to manage and distribute application state.
import React, { createContext, useContext, useState, ReactNode } from 'react';
interface User {
id: number;
name: string;
}
interface UserContextType {
user: User | null;
setUser: React.Dispatch
React.SetStateAction<User | null>>;
}
const UserContext = createContext<UserContextType | undefined>(undefined);
const UserProvider: React.FC<{children: ReactNode}> = ({ children }) => {
const [user, setUser] = useState<User | null>(null);
return (
<UserContext.Provider value={{ user, setUser }}>
{children}
</UserContext.Provider>
);
};
const useUser = () => {
const context = useContext(UserContext);
if (context === undefined) {
throw new Error('useUser must be used within a UserProvider');
}
return context;
};
// Example of a component that uses the useUser hook
const UserProfile: React.FC = () => {
const { user, setUser } = useUser();
return (
<div>
{user ? (
<h1>Welcome, {user.name}</h1>
) : (
<button onClick={() => setUser({ id: 1, name: 'Jane Doe' })}>Login</button>
)}
</div>
);
};
// Usage of UserProvider in the app
const App: React.FC = () => {
return (
<UserProvider>
<UserProfile />
</UserProvider>
);
};
export default App;
TypeScript's utility types in a React context to demonstrate their usefulness in state management and component prop manipulation.
import React from 'react';
interface Props {
name: string;
age: number;
email: string;
}
// Using Partial to make all properties optional
const updateUser = (user: Partial<Props>) => {
console.log('Updating user:', user);
};
const UserComponent: React.FC = () => {
return (
<button onClick={() => updateUser({ name: 'Alice' })}>
Update Name
</button>
);
};
export default UserComponent;
Define a reducer using TypeScript for more complex state management scenarios, such as handling a shopping cart.
import React, { useReducer } from 'react';
interface CartItem {
id: number;
name: string;
quantity: number;
}
type CartState = CartItem[];
type CartAction =
| { type: 'add'; item: CartItem }
| { type: 'remove'; id: number }
| { type: 'increase'; id: number }
| { type: 'decrease'; id: number };
const cartReducer = (state: CartState, action: CartAction): CartState => {
switch (action.type) {
case 'add':
return [...state, action.item];
case 'remove':
return state.filter(item => item.id !== action.id);
case 'increase':
return state.map(item => item.id === action.id ? { ...item, quantity: item.quantity + 1 } : item);
case 'decrease':
return state.map(item => item.id === action.id ? { ...item, quantity: Math.max(item.quantity - 1, 0) } : item);
default:
return state;
}
};
const CartComponent: React.FC = () => {
const [cart, dispatch] = useReducer(cartReducer, []);
return (
<div>
{cart.map(item => (
<div key={item.id}>
<div>{item.name} - Quantity: {item.quantity}</div>
<button onClick={() => dispatch({ type: 'increase', id: item.id })}>+</button>
<button onClick={() => dispatch({ type: 'decrease', id: item.id })}>-</button>
<button onClick={() => dispatch({ type: 'remove', id: item.id })}>Remove</button>
</div>
))}
</div>
);
};
export default CartComponent;