TypeScript React Component Example
This snippet shows a TypeScript React component with proper typing.
TYPESCRIPT
1
2 import React, { useState, useEffect } from 'react';
3
4 interface User {
5 id: number;
6 name: string;
7 email: string;
8 role: 'admin' | 'user' | 'moderator';
9 }
10
11 interface UserListProps {
12 initialUsers: User[];
13 onUserSelect?: (user: User) => void;
14 }
15
16 const UserList: React.FC<UserListProps> = ({
17 initialUsers,
18 onUserSelect
19 }) => {
20 const [users, setUsers] = useState<User[]>(initialUsers);
21 const [filter, setFilter] = useState<string>('');
22 const [loading, setLoading] = useState<boolean>(false);
23
24 useEffect(() => {
25 // Fetch users from API
26 const fetchUsers = async () => {
27 setLoading(true);
28 try {
29 const response = await fetch('/api/users');
30 const data = await response.json();
31 setUsers(data);
32 } catch (error) {
33 console.error('Failed to fetch users:', error);
34 } finally {
35 setLoading(false);
36 }
37 };
38
39 fetchUsers();
40 }, []);
41
42 const filteredUsers = users.filter(user =>
43 user.name.toLowerCase().includes(filter.toLowerCase()) ||
44 user.email.toLowerCase().includes(filter.toLowerCase())
45 );
46
47 const handleUserClick = (user: User) => {
48 onUserSelect?.(user);
49 };
50
51 if (loading) {
52 return <div>Loading users...</div>;
53 }
54
55 return (
56 <div className="user-list">
57 <input
58 type="text"
59 placeholder="Filter users..."
60 value={filter}
61 onChange={(e) => setFilter(e.target.value)}
62 className="filter-input"
63 />
64 <ul className="user-items">
65 {filteredUsers.map(user => (
66 <li
67 key={user.id}
68 onClick={() => handleUserClick(user)}
69 className={`user-item ${user.role}`}
70 >
71 <span className="user-name">{user.name}</span>
72 <span className="user-email">{user.email}</span>
73 <span className="user-role">{user.role}</span>
74 </li>
75 ))}
76 </ul>
77 </div>
78 );
79 };
80
81 export default UserList;