0
# Replace Transitions
1
2
The ReplaceTransition component is a specialized transition component that animates between exactly two children. It provides a controlled way to switch between two specific components with proper transition timing.
3
4
## Capabilities
5
6
### ReplaceTransition Component
7
8
Animates between two children based on the `in` prop value, using TransitionGroup internally for coordination.
9
10
```javascript { .api }
11
/**
12
* Specialized transition component that animates between exactly two children
13
* @param props - ReplaceTransition props
14
* @returns JSX element managing two-child transitions
15
*/
16
function ReplaceTransition({
17
in: inProp,
18
children,
19
onEnter,
20
onEntering,
21
onEntered,
22
onExit,
23
onExiting,
24
onExited,
25
...otherProps
26
}): JSX.Element;
27
28
interface ReplaceTransitionProps {
29
/** Controls which child is shown (true = first child, false = second child) */
30
in: boolean;
31
/** Must be exactly two transition components (Transition or CSSTransition) */
32
children: [React.ReactElement, React.ReactElement];
33
/** Callback fired before the "entering" status is applied */
34
onEnter?: (node?: HTMLElement) => void;
35
/** Callback fired after the "entering" status is applied */
36
onEntering?: (node?: HTMLElement) => void;
37
/** Callback fired after the "entered" status is applied */
38
onEntered?: (node?: HTMLElement) => void;
39
/** Callback fired before the "exiting" status is applied */
40
onExit?: (node?: HTMLElement) => void;
41
/** Callback fired after the "exiting" status is applied */
42
onExiting?: (node?: HTMLElement) => void;
43
/** Callback fired after the "exited" status is applied */
44
onExited?: (node?: HTMLElement) => void;
45
}
46
```
47
48
**Usage Examples:**
49
50
```javascript
51
import React, { useState } from 'react';
52
import { ReplaceTransition, CSSTransition } from 'react-transition-group';
53
import './replace.css';
54
55
function ReplaceExample() {
56
const [showFirst, setShowFirst] = useState(true);
57
58
return (
59
<div>
60
<ReplaceTransition in={showFirst}>
61
<CSSTransition
62
timeout={300}
63
classNames="fade"
64
key="first"
65
>
66
<div className="content first">
67
First Content
68
</div>
69
</CSSTransition>
70
71
<CSSTransition
72
timeout={300}
73
classNames="fade"
74
key="second"
75
>
76
<div className="content second">
77
Second Content
78
</div>
79
</CSSTransition>
80
</ReplaceTransition>
81
82
<button onClick={() => setShowFirst(!showFirst)}>
83
Switch Content
84
</button>
85
</div>
86
);
87
}
88
89
// Image slider with replace transitions
90
function ImageSlider() {
91
const [currentIndex, setCurrentIndex] = useState(0);
92
const images = [
93
{ src: 'image1.jpg', alt: 'First image' },
94
{ src: 'image2.jpg', alt: 'Second image' }
95
];
96
97
return (
98
<div className="slider">
99
<ReplaceTransition in={currentIndex === 0}>
100
<CSSTransition
101
timeout={500}
102
classNames="slide"
103
key="image1"
104
>
105
<img
106
src={images[0].src}
107
alt={images[0].alt}
108
className="slider-image"
109
/>
110
</CSSTransition>
111
112
<CSSTransition
113
timeout={500}
114
classNames="slide"
115
key="image2"
116
>
117
<img
118
src={images[1].src}
119
alt={images[1].alt}
120
className="slider-image"
121
/>
122
</CSSTransition>
123
</ReplaceTransition>
124
125
<button
126
onClick={() => setCurrentIndex(currentIndex === 0 ? 1 : 0)}
127
>
128
Next Image
129
</button>
130
</div>
131
);
132
}
133
```
134
135
### Component Behavior
136
137
ReplaceTransition automatically:
138
139
1. **Manages two children**: Always expects exactly two child components
140
2. **Controls visibility**: Shows first child when `in={true}`, second child when `in={false}`
141
3. **Handles transitions**: Uses TransitionGroup internally to coordinate enter/exit timing
142
4. **Forwards callbacks**: Passes lifecycle callbacks to the appropriate child component
143
144
### Children Requirements
145
146
ReplaceTransition requires exactly two children:
147
148
```javascript
149
// ✅ Correct - exactly two children
150
<ReplaceTransition in={showFirst}>
151
<CSSTransition timeout={200} classNames="fade" key="first">
152
<div>First</div>
153
</CSSTransition>
154
<CSSTransition timeout={200} classNames="fade" key="second">
155
<div>Second</div>
156
</CSSTransition>
157
</ReplaceTransition>
158
159
// ❌ Incorrect - wrong number of children
160
<ReplaceTransition in={showFirst}>
161
<CSSTransition timeout={200} classNames="fade">
162
<div>Only one child</div>
163
</CSSTransition>
164
</ReplaceTransition>
165
```
166
167
### Lifecycle Callback Flow
168
169
ReplaceTransition maps its lifecycle callbacks to the child components in a specific way:
170
171
- When transitioning **to first child** (`in={true}`):
172
- ReplaceTransition's `onEnter`, `onEntering`, `onEntered` map to first child's corresponding callbacks
173
- First child transitions in normally
174
175
- When transitioning **to second child** (`in={false}`):
176
- ReplaceTransition's `onEnter`, `onEntering`, `onEntered` map to second child's `onEnter`, `onEntering`, `onEntered` callbacks
177
- Second child transitions in (confusingly named, but this is how the source maps callbacks)
178
179
```javascript
180
function CallbackExample() {
181
const [active, setActive] = useState(true);
182
183
return (
184
<ReplaceTransition
185
in={active}
186
onEnter={() => console.log('Child entering')}
187
onExit={() => console.log('Child exiting')}
188
>
189
<CSSTransition
190
timeout={200}
191
classNames="first"
192
key="first"
193
onEntered={() => console.log('First child entered')}
194
>
195
<div>First</div>
196
</CSSTransition>
197
198
<CSSTransition
199
timeout={200}
200
classNames="second"
201
key="second"
202
onEntered={() => console.log('Second child entered')}
203
>
204
<div>Second</div>
205
</CSSTransition>
206
</ReplaceTransition>
207
);
208
}
209
```
210
211
### Example CSS for Replace Transitions
212
213
```css
214
/* Fade transition */
215
.fade-enter {
216
opacity: 0;
217
}
218
219
.fade-enter-active {
220
opacity: 1;
221
transition: opacity 300ms ease-in-out;
222
}
223
224
.fade-exit {
225
opacity: 1;
226
}
227
228
.fade-exit-active {
229
opacity: 0;
230
transition: opacity 300ms ease-in-out;
231
}
232
233
/* Slide transition for image replacement */
234
.slide-enter {
235
transform: translateX(100%);
236
}
237
238
.slide-enter-active {
239
transform: translateX(0);
240
transition: transform 500ms ease-out;
241
}
242
243
.slide-exit {
244
transform: translateX(0);
245
}
246
247
.slide-exit-active {
248
transform: translateX(-100%);
249
transition: transform 500ms ease-in;
250
}
251
252
/* Cross-fade transition */
253
.crossfade-enter {
254
opacity: 0;
255
position: absolute;
256
top: 0;
257
left: 0;
258
right: 0;
259
}
260
261
.crossfade-enter-active {
262
opacity: 1;
263
transition: opacity 400ms ease-in-out;
264
}
265
266
.crossfade-exit {
267
opacity: 1;
268
position: absolute;
269
top: 0;
270
left: 0;
271
right: 0;
272
}
273
274
.crossfade-exit-active {
275
opacity: 0;
276
transition: opacity 400ms ease-in-out;
277
}
278
```
279
280
### Use Cases
281
282
ReplaceTransition is ideal for:
283
284
- **Binary state switches**: Toggle between two distinct states
285
- **Before/after comparisons**: Show two versions of content
286
- **Image comparisons**: Switch between two images with transition
287
- **Form steps**: Navigate between two specific form sections
288
- **Content previews**: Switch between edit and preview modes
289
290
For more complex switching scenarios with multiple options, consider using SwitchTransition instead.