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

Tags

#react#typescript#best-practices#javascript