React and TypeScript: Best Practices for 2024
Learn the best practices for building React applications with TypeScript, including type safety, component patterns, and performance optimization.
React and TypeScript: Best Practices for 2024
TypeScript has become the de facto standard for building large-scale React applications. In this post, I'll share some best practices I've learned over the years.
1. Use Functional Components with Proper Typing
Always type your functional components properly:
interface ButtonProps {
label: string;
onClick: () => void;
variant?: 'primary' | 'secondary';
}
const Button: React.FC<ButtonProps> = ({ label, onClick, variant = 'primary' }) => {
return (
<button onClick={onClick} className={`btn btn-${variant}`}>
{label}
</button>
);
};
2. Leverage Type Inference
TypeScript is smart enough to infer types in many cases. Let it work for you:
// No need to explicitly type the return value
const getUserName = (user: User) => {
return user.firstName + ' ' + user.lastName;
};
// TypeScript knows this is a string[]
const names = users.map(user => user.name);
3. Use Discriminated Unions for State
This pattern is incredibly useful for managing complex state:
type LoadingState =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'success'; data: Data }
| { status: 'error'; error: Error };
const Component: React.FC = () => {
const [state, setState] = useState<LoadingState>({ status: 'idle' });
// TypeScript knows what properties are available
if (state.status === 'success') {
console.log(state.data); // ✅ data is available
}
};
4. Create Reusable Generic Components
Generic components can work with multiple types while maintaining type safety:
interface ListProps<T> {
items: T[];
renderItem: (item: T) => React.ReactNode;
}
function List<T>({ items, renderItem }: ListProps<T>) {
return (
<ul>
{items.map((item, index) => (
<li key={index}>{renderItem(item)}</li>
))}
</ul>
);
}
5. Use as const for Better Type Inference
const COLORS = {
primary: '#c9f31d',
dark: '#0a0a0a',
} as const;
type Color = typeof COLORS[keyof typeof COLORS];
// Color is '#c9f31d' | '#0a0a0a'
Conclusion
These practices have helped me write more maintainable and bug-free React applications. TypeScript's type system is powerful, and when used correctly, it can catch errors before they reach production.
What are your favorite React + TypeScript patterns? Let me know!
📚 References
- React Official Documentation - Official React documentation with comprehensive guides and API reference
- TypeScript Official Documentation - TypeScript handbook and language reference
- React TypeScript Cheatsheet - Community-driven cheatsheet for TypeScript with React
- TypeScript Deep Dive - Open source book on TypeScript
- React Patterns - Collection of design patterns for React development