0
# Switch/Case Pattern
1
2
Multi-condition branching components that provide a clean alternative to multiple if-else chains. Similar to JavaScript switch statements but with React component syntax.
3
4
## Capabilities
5
6
### Switch Component
7
8
Container component that evaluates multiple Case conditions and renders the first matching Case or the first Default component.
9
10
```typescript { .api }
11
/**
12
* Container for <Case /> and <Default /> blocks.
13
* Renders the first matching Case, or the first encountered Default (or null).
14
* Can contain any number of <Case /> and one <Default /> blocks.
15
*/
16
const Switch: FC<{
17
children: ReactNode;
18
}>;
19
```
20
21
**Usage Examples:**
22
23
```typescript
24
import { Switch, Case, Default } from "react-if";
25
26
// Basic switch pattern
27
<Switch>
28
<Case condition={status === "loading"}>
29
<LoadingSpinner />
30
</Case>
31
<Case condition={status === "error"}>
32
<ErrorMessage />
33
</Case>
34
<Case condition={status === "success"}>
35
<SuccessContent />
36
</Case>
37
<Default>
38
<div>Unknown status</div>
39
</Default>
40
</Switch>
41
42
// With function conditions
43
<Switch>
44
<Case condition={() => score >= 90}>
45
<Grade level="A" />
46
</Case>
47
<Case condition={() => score >= 80}>
48
<Grade level="B" />
49
</Case>
50
<Case condition={() => score >= 70}>
51
<Grade level="C" />
52
</Case>
53
<Default>
54
<Grade level="F" />
55
</Default>
56
</Switch>
57
```
58
59
### Case Component
60
61
Conditional branch within a Switch that renders when its condition is true and it's the first matching case.
62
63
```typescript { .api }
64
/**
65
* If the Case is the first one to have its condition evaluate to true
66
* inside the parent <Switch />, it will be the only one rendered.
67
*/
68
const Case: FC<{
69
condition: BooleanLike | (() => BooleanLike);
70
children?: ReactNode | (() => JSX.Element);
71
}>;
72
```
73
74
**Usage Examples:**
75
76
```typescript
77
// Static condition
78
<Case condition={userRole === "admin"}>
79
<AdminPanel />
80
</Case>
81
82
// Function condition for complex logic
83
<Case condition={() => {
84
const permissions = getUserPermissions();
85
return permissions.includes("write");
86
}}>
87
<EditButton />
88
</Case>
89
90
// Function children for lazy evaluation
91
<Case condition={shouldShowChart}>
92
{() => <ChartComponent data={processChartData()} />}
93
</Case>
94
```
95
96
### Default Component
97
98
Fallback component that renders when no Case conditions match within a Switch.
99
100
```typescript { .api }
101
/**
102
* If no Case has its condition evaluate to true inside the parent <Switch />,
103
* the first Default will be the only one rendered.
104
*/
105
const Default: FC<{
106
children?: ReactNode | (() => JSX.Element);
107
}>;
108
```
109
110
**Usage Examples:**
111
112
```typescript
113
// Static fallback content
114
<Default>
115
<div className="fallback">No matching condition</div>
116
</Default>
117
118
// Function children
119
<Default>
120
{() => <DefaultComponent />}
121
</Default>
122
123
// Error fallback
124
<Default>
125
<div className="error">
126
<h3>Unexpected State</h3>
127
<p>Please contact support if this issue persists.</p>
128
</div>
129
</Default>
130
```
131
132
## Advanced Usage Patterns
133
134
### Complex Multi-Condition Logic
135
136
```typescript
137
const StatusDisplay = ({ user, connection, data }) => (
138
<Switch>
139
<Case condition={!connection.isOnline}>
140
<OfflineIndicator />
141
</Case>
142
<Case condition={user.isGuest}>
143
<GuestModeNotice />
144
</Case>
145
<Case condition={() => data.length === 0}>
146
<EmptyState />
147
</Case>
148
<Case condition={() => data.some(item => item.isHighPriority)}>
149
<PriorityDataView data={data} />
150
</Case>
151
<Default>
152
<StandardDataView data={data} />
153
</Default>
154
</Switch>
155
);
156
```
157
158
### Nested Switch Statements
159
160
```typescript
161
<Switch>
162
<Case condition={userType === "premium"}>
163
<Switch>
164
<Case condition={subscription.isActive}>
165
<PremiumDashboard />
166
</Case>
167
<Default>
168
<SubscriptionExpiredNotice />
169
</Default>
170
</Switch>
171
</Case>
172
<Case condition={userType === "basic"}>
173
<BasicDashboard />
174
</Case>
175
<Default>
176
<WelcomeScreen />
177
</Default>
178
</Switch>
179
```
180
181
### Performance Considerations
182
183
Use function children to avoid expensive computations in non-matching cases:
184
185
```typescript
186
<Switch>
187
<Case condition={renderMode === "chart"}>
188
{() => {
189
// Only process data when this case matches
190
const chartData = processDataForChart(rawData);
191
return <Chart data={chartData} />;
192
}}
193
</Case>
194
<Case condition={renderMode === "table"}>
195
{() => {
196
// Only process data when this case matches
197
const tableData = processDataForTable(rawData);
198
return <Table data={tableData} />;
199
}}
200
</Case>
201
<Default>
202
<div>Select a view mode</div>
203
</Default>
204
</Switch>
205
```
206
207
## Type Definitions
208
209
```typescript { .api }
210
type BooleanLike = boolean | string | number | null | undefined | ExtendablePromise<any>;
211
212
type ComponentWithConditionPropsWithFunctionChildren<P = {}> = P & {
213
condition: (() => BooleanLike) | BooleanLike;
214
children?: ReactNode | undefined | ((...args: unknown[]) => JSX.Element);
215
};
216
217
type FunctionComponentWithImplicitChildren<P = {}> = FunctionComponent<{
218
children?: ReactNode | undefined | ((...args: unknown[]) => JSX.Element);
219
} & P>;
220
```