0
# React Hooks
1
2
Lifecycle and state management hooks for React components in Taro applications, providing seamless integration with React Native lifecycle events.
3
4
## Capabilities
5
6
### Page Lifecycle Hooks
7
8
React hooks that integrate with Taro's page lifecycle events.
9
10
```typescript { .api }
11
/**
12
* Hook that triggers when page is shown
13
* @param callback Function to execute when page shows
14
*/
15
function useDidShow(callback: () => void): void;
16
17
/**
18
* Hook that triggers when page is hidden
19
* @param callback Function to execute when page hides
20
*/
21
function useDidHide(callback: () => void): void;
22
23
/**
24
* Hook that triggers when page loads
25
* @param callback Function to execute when page loads
26
*/
27
function useLoad(callback: () => void): void;
28
29
/**
30
* Hook that triggers when page is ready
31
* @param callback Function to execute when page is ready
32
*/
33
function useReady(callback: () => void): void;
34
35
/**
36
* Hook that triggers when page unloads
37
* @param callback Function to execute when page unloads
38
*/
39
function useUnload(callback: () => void): void;
40
```
41
42
**Usage Examples:**
43
44
```typescript
45
import React, { useState } from 'react';
46
import { useDidShow, useDidHide, useLoad, useReady, useUnload } from "@tarojs/taro-rn";
47
48
function MyPage() {
49
const [data, setData] = useState(null);
50
const [isVisible, setIsVisible] = useState(true);
51
52
useLoad(() => {
53
console.log('Page loaded - initial setup');
54
// Initialize page data
55
});
56
57
useReady(() => {
58
console.log('Page ready - DOM is available');
59
// Perform DOM operations if needed
60
});
61
62
useDidShow(() => {
63
console.log('Page shown - refresh data');
64
setIsVisible(true);
65
66
// Refresh data when page becomes visible
67
fetchLatestData();
68
});
69
70
useDidHide(() => {
71
console.log('Page hidden - pause operations');
72
setIsVisible(false);
73
74
// Pause expensive operations
75
pauseAnimations();
76
});
77
78
useUnload(() => {
79
console.log('Page unloading - cleanup');
80
81
// Cleanup resources
82
clearTimers();
83
saveUserProgress();
84
});
85
86
return (
87
<View>
88
<Text>Page is {isVisible ? 'visible' : 'hidden'}</Text>
89
</View>
90
);
91
}
92
```
93
94
### App Lifecycle Hooks
95
96
Hooks for application-level lifecycle events.
97
98
```typescript { .api }
99
/**
100
* Hook that triggers when app launches
101
* @param callback Function to execute when app launches, receives launch options
102
*/
103
function useLaunch(callback: (options: {
104
path: string;
105
query: Record<string, any>;
106
scene: number;
107
shareTicket: string;
108
referrerInfo: any;
109
}) => void): void;
110
111
/**
112
* Hook that triggers when page is not found
113
* @param callback Function to execute when page not found
114
*/
115
function usePageNotFound(callback: (res: {
116
path: string;
117
query: Record<string, any>;
118
isEntryPage: boolean;
119
}) => void): void;
120
```
121
122
**Usage Examples:**
123
124
```typescript
125
import { useLaunch, usePageNotFound } from "@tarojs/taro-rn";
126
127
function App() {
128
useLaunch((options) => {
129
console.log('App launched with path:', options.path);
130
console.log('Launch query:', options.query);
131
console.log('Launch scene:', options.scene);
132
133
// Initialize app based on launch parameters
134
if (options.query.userId) {
135
initializeUserSession(options.query.userId);
136
}
137
138
// Track app launch
139
analytics.track('app_launch', {
140
path: options.path,
141
scene: options.scene
142
});
143
});
144
145
usePageNotFound((res) => {
146
console.log('Page not found:', res.path);
147
148
// Redirect to error page or home
149
Taro.redirectTo({
150
url: '/pages/error/index?type=404&path=' + encodeURIComponent(res.path)
151
});
152
});
153
154
return <AppContent />;
155
}
156
```
157
158
### Page Interaction Hooks
159
160
Hooks for page scroll, pull-to-refresh, and other interactions.
161
162
```typescript { .api }
163
/**
164
* Hook that triggers on page scroll
165
* @param callback Function to execute on page scroll
166
*/
167
function usePageScroll(callback: (res: {
168
scrollTop: number;
169
}) => void): void;
170
171
/**
172
* Hook that triggers when reaching bottom of page
173
* @param callback Function to execute when reaching bottom
174
*/
175
function useReachBottom(callback: () => void): void;
176
177
/**
178
* Hook that triggers on pull-down refresh
179
* @param callback Function to execute on pull-down refresh
180
*/
181
function usePullDownRefresh(callback: () => void): void;
182
183
/**
184
* Hook that triggers on window resize
185
* @param callback Function to execute on window resize
186
*/
187
function useResize(callback: (res: {
188
size: {
189
windowWidth: number;
190
windowHeight: number;
191
};
192
}) => void): void;
193
```
194
195
**Usage Examples:**
196
197
```typescript
198
import React, { useState } from 'react';
199
import {
200
usePageScroll,
201
useReachBottom,
202
usePullDownRefresh,
203
useResize,
204
stopPullDownRefresh
205
} from "@tarojs/taro-rn";
206
207
function ScrollablePage() {
208
const [scrollTop, setScrollTop] = useState(0);
209
const [items, setItems] = useState([]);
210
const [loading, setLoading] = useState(false);
211
212
usePageScroll((res) => {
213
setScrollTop(res.scrollTop);
214
215
// Show/hide back-to-top button
216
if (res.scrollTop > 200) {
217
showBackToTopButton();
218
} else {
219
hideBackToTopButton();
220
}
221
});
222
223
useReachBottom(() => {
224
if (!loading) {
225
console.log('Reached bottom - load more data');
226
loadMoreData();
227
}
228
});
229
230
usePullDownRefresh(() => {
231
console.log('Pull down refresh triggered');
232
refreshData();
233
});
234
235
useResize((res) => {
236
console.log('Window resized:', res.size);
237
238
// Adapt layout to new size
239
adaptLayoutToSize(res.size);
240
});
241
242
const refreshData = async () => {
243
setLoading(true);
244
try {
245
const newData = await fetchLatestData();
246
setItems(newData);
247
} finally {
248
setLoading(false);
249
stopPullDownRefresh();
250
}
251
};
252
253
const loadMoreData = async () => {
254
setLoading(true);
255
try {
256
const moreData = await fetchMoreData(items.length);
257
setItems([...items, ...moreData]);
258
} finally {
259
setLoading(false);
260
}
261
};
262
263
return (
264
<View>
265
<Text>Scroll position: {scrollTop}</Text>
266
{items.map((item, index) => (
267
<View key={index}>{item.title}</View>
268
))}
269
{loading && <Text>Loading...</Text>}
270
</View>
271
);
272
}
273
```
274
275
### Navigation Hooks
276
277
Hooks for navigation and routing information.
278
279
```typescript { .api }
280
/**
281
* Get router information for current page
282
* @returns Router information including path and params
283
*/
284
function useRouter(): {
285
params: Record<string, string>;
286
path: string;
287
};
288
289
/**
290
* Hook that triggers when tab item is tapped
291
* @param callback Function to execute when tab is tapped
292
*/
293
function useTabItemTap(callback: (res: {
294
index: number;
295
pagePath: string;
296
text: string;
297
}) => void): void;
298
```
299
300
**Usage Examples:**
301
302
```typescript
303
import React, { useEffect, useState } from 'react';
304
import { useRouter, useTabItemTap } from "@tarojs/taro-rn";
305
306
function ProductDetailPage() {
307
const router = useRouter();
308
const [product, setProduct] = useState(null);
309
310
useEffect(() => {
311
console.log('Current page path:', router.path);
312
console.log('Page params:', router.params);
313
314
// Get product ID from URL parameters
315
const productId = router.params.id;
316
if (productId) {
317
loadProduct(productId);
318
}
319
}, [router.params]);
320
321
const loadProduct = async (id: string) => {
322
try {
323
const productData = await fetchProduct(id);
324
setProduct(productData);
325
} catch (error) {
326
console.error('Failed to load product:', error);
327
}
328
};
329
330
return (
331
<View>
332
<Text>Product ID: {router.params.id}</Text>
333
{product && (
334
<View>
335
<Text>{product.name}</Text>
336
<Text>{product.description}</Text>
337
</View>
338
)}
339
</View>
340
);
341
}
342
343
function TabBarContainer() {
344
useTabItemTap((res) => {
345
console.log('Tab tapped:', res.index, res.pagePath);
346
347
// Track tab usage
348
analytics.track('tab_tap', {
349
index: res.index,
350
pagePath: res.pagePath,
351
text: res.text
352
});
353
354
// Handle specific tab actions
355
if (res.index === 0) {
356
// Home tab - refresh data
357
refreshHomeData();
358
} else if (res.index === 2) {
359
// Profile tab - check login status
360
checkLoginStatus();
361
}
362
});
363
364
return <TabBarContent />;
365
}
366
```
367
368
## Hook Patterns
369
370
### Combining Lifecycle Hooks
371
372
```typescript
373
import React, { useState, useRef } from 'react';
374
import {
375
useDidShow,
376
useDidHide,
377
useUnload,
378
usePageScroll
379
} from "@tarojs/taro-rn";
380
381
function usePageVisibility() {
382
const [isVisible, setIsVisible] = useState(true);
383
const [hasBeenVisible, setHasBeenVisible] = useState(false);
384
385
useDidShow(() => {
386
setIsVisible(true);
387
setHasBeenVisible(true);
388
});
389
390
useDidHide(() => {
391
setIsVisible(false);
392
});
393
394
return { isVisible, hasBeenVisible };
395
}
396
397
function useScrollPosition() {
398
const [scrollTop, setScrollTop] = useState(0);
399
const [isScrolling, setIsScrolling] = useState(false);
400
const scrollTimer = useRef<NodeJS.Timeout>();
401
402
usePageScroll((res) => {
403
setScrollTop(res.scrollTop);
404
setIsScrolling(true);
405
406
// Clear existing timer
407
if (scrollTimer.current) {
408
clearTimeout(scrollTimer.current);
409
}
410
411
// Set timer to detect scroll end
412
scrollTimer.current = setTimeout(() => {
413
setIsScrolling(false);
414
}, 150);
415
});
416
417
useUnload(() => {
418
if (scrollTimer.current) {
419
clearTimeout(scrollTimer.current);
420
}
421
});
422
423
return { scrollTop, isScrolling };
424
}
425
426
// Usage in component
427
function MyComponent() {
428
const { isVisible, hasBeenVisible } = usePageVisibility();
429
const { scrollTop, isScrolling } = useScrollPosition();
430
431
return (
432
<View>
433
<Text>Page visible: {isVisible ? 'Yes' : 'No'}</Text>
434
<Text>Has been visible: {hasBeenVisible ? 'Yes' : 'No'}</Text>
435
<Text>Scroll position: {scrollTop}</Text>
436
<Text>Currently scrolling: {isScrolling ? 'Yes' : 'No'}</Text>
437
</View>
438
);
439
}
440
```
441
442
### Resource Management
443
444
```typescript
445
import { useState, useRef } from 'react';
446
import { useDidShow, useDidHide, useUnload } from "@tarojs/taro-rn";
447
448
function useResourceManager() {
449
const [resources, setResources] = useState(new Set());
450
const timers = useRef(new Set());
451
const intervals = useRef(new Set());
452
453
const addTimer = (timer: NodeJS.Timeout) => {
454
timers.current.add(timer);
455
return timer;
456
};
457
458
const addInterval = (interval: NodeJS.Timeout) => {
459
intervals.current.add(interval);
460
return interval;
461
};
462
463
const cleanup = () => {
464
// Clear all timers
465
timers.current.forEach(timer => clearTimeout(timer));
466
timers.current.clear();
467
468
// Clear all intervals
469
intervals.current.forEach(interval => clearInterval(interval));
470
intervals.current.clear();
471
472
// Clear other resources
473
resources.forEach(resource => {
474
if (typeof resource.cleanup === 'function') {
475
resource.cleanup();
476
}
477
});
478
setResources(new Set());
479
};
480
481
useDidHide(() => {
482
// Pause non-critical operations when page is hidden
483
pauseOperations();
484
});
485
486
useDidShow(() => {
487
// Resume operations when page is shown
488
resumeOperations();
489
});
490
491
useUnload(() => {
492
cleanup();
493
});
494
495
return {
496
addTimer,
497
addInterval,
498
addResource: (resource) => setResources(prev => new Set([...prev, resource])),
499
cleanup
500
};
501
}
502
```