Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Apply React composition patterns to build flexible, maintainable components without boolean prop sprawl
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
rules/architecture-avoid-boolean-props.md
1---2title: Avoid Boolean Prop Proliferation3impact: CRITICAL4impactDescription: prevents unmaintainable component variants5tags: composition, props, architecture6---78## Avoid Boolean Prop Proliferation910Don't add boolean props like `isThread`, `isEditing`, `isDMThread` to customize11component behavior. Each boolean doubles possible states and creates12unmaintainable conditional logic. Use composition instead.1314**Incorrect (boolean props create exponential complexity):**1516```tsx17function Composer({18onSubmit,19isThread,20channelId,21isDMThread,22dmId,23isEditing,24isForwarding,25}: Props) {26return (27<form>28<Header />29<Input />30{isDMThread ? (31<AlsoSendToDMField id={dmId} />32) : isThread ? (33<AlsoSendToChannelField id={channelId} />34) : null}35{isEditing ? (36<EditActions />37) : isForwarding ? (38<ForwardActions />39) : (40<DefaultActions />41)}42<Footer onSubmit={onSubmit} />43</form>44)45}46```4748**Correct (composition eliminates conditionals):**4950```tsx51// Channel composer52function ChannelComposer() {53return (54<Composer.Frame>55<Composer.Header />56<Composer.Input />57<Composer.Footer>58<Composer.Attachments />59<Composer.Formatting />60<Composer.Emojis />61<Composer.Submit />62</Composer.Footer>63</Composer.Frame>64)65}6667// Thread composer - adds "also send to channel" field68function ThreadComposer({ channelId }: { channelId: string }) {69return (70<Composer.Frame>71<Composer.Header />72<Composer.Input />73<AlsoSendToChannelField id={channelId} />74<Composer.Footer>75<Composer.Formatting />76<Composer.Emojis />77<Composer.Submit />78</Composer.Footer>79</Composer.Frame>80)81}8283// Edit composer - different footer actions84function EditComposer() {85return (86<Composer.Frame>87<Composer.Input />88<Composer.Footer>89<Composer.Formatting />90<Composer.Emojis />91<Composer.CancelEdit />92<Composer.SaveEdit />93</Composer.Footer>94</Composer.Frame>95)96}97```9899Each variant is explicit about what it renders. We can share internals without100sharing a single monolithic parent.101