Skip to main content

Command Palette

Search for a command to run...

How to write clean props in reactjs

A better props contract is highly scalable and modular to build better application

Updated
2 min readView as Markdown
V
Co-founder & Building @Quizforces | Web Developer

In reactjs passing ( writing ) props seems very simple. Until it comes to scalablity.

Hello, I'm Vikash.

Source ( Unorganized )

interface UserCardProps {
  user: UserDomainModel; 
  
  isSmall?: boolean;
  isLarge?: boolean;
  isDarkMode?: boolean;
  hasBorder?: boolean;
  hasShadow?: boolean;
  
  setIsEditing: React.Dispatch<React.SetStateAction<boolean>>;
  setUserData: React.Dispatch<React.SetStateAction<UserDomainModel>>;
  
  showEditButton?: boolean;
  showFollowButton?: boolean;
  showDeleteButton?: boolean;
  
  onAction?: (type: string, data: any) => void;
}

export const UserProfileCard = ({
  user,
  isSmall,
  isLarge,
  setIsEditing,
  showEditButton,
  onAction,
}: UserCardProps) => {
  return (
    <div className={`card ${isSmall ? 'sm' : isLarge ? 'lg' : 'md'}`}>
      <img src={user.profile.meta.avatar.cdnUrl} alt={user.personalInfo.firstName} />
      <h3>{user.personalInfo.firstName} {user.personalInfo.lastName}</h3>
      
      {showEditButton && (
        <button onClick={() => setIsEditing(true)}>Edit</button>
      )}
      <button onClick={() => onAction?.('DELETE', user.id)}>Delete</button>
    </div>
  );
};

Source ( Clean )

interface UserCardProps {
  userId: string;
  name: string;
  avatarUrl?: string;

  size?: 'sm' | 'md' | 'lg';
  variant?: 'flat' | 'outlined' | 'elevated';

  onSelect?: (userId: string) => void;

  actionSlot?: React.ReactNode;
}

export const UserProfileCard = ({
  userId,
  name,
  avatarUrl,
  size = 'md',
  variant = 'flat',
  onSelect,
  actionSlot,
}: UserCardProps) => {
  return (
    <div 
      className={`card card--${size} card--${variant}`}
      onClick={() => onSelect?.(userId)}
    >
      {avatarUrl && <img src={avatarUrl} alt={name} />}
      <h3>{name}</h3>
      
      {/* Slot rendering keeps child clean of button logic */}
      {actionSlot && <div className="card__actions">{actionSlot}</div>}
    </div>
  );
};

Writing better props solves so many hurdles in future debugging and keeps the development flow smooth and predictable.

Thanks for Reading

T

The enum-over-boolean-flags swap is the strongest part, isSmall plus isLarge lets you represent both true which is meaningless. Two things on the clean version though. Making the whole card clickable by putting onClick on the div is a step back from a real button for a11y and keyboard, and since actionSlot renders inside that div, clicking Edit or Delete also fires onSelect unless you stopPropagation, which is easy to miss. And fully flattening the domain model works for three fields but if the card needs eight you have traded one prop for a wide order-sensitive call site. The middle ground is a narrow view-model type the card owns and the parent maps into, you get the decoupling from UserDomainModel without the prop explosion.