0
# Core Setup and Configuration
1
2
Core functionality for initializing Why Did You Render with React and configuring tracking options.
3
4
## Capabilities
5
6
### Main Library Function
7
8
Initializes Why Did You Render by monkey patching React with re-render tracking capabilities.
9
10
```typescript { .api }
11
/**
12
* Initialize Why Did You Render with React instance and configuration options
13
* @param React - The React instance to patch
14
* @param options - Configuration options for tracking behavior
15
* @returns The patched React instance with additional WDYR properties
16
*/
17
function whyDidYouRender(
18
React: typeof React,
19
options?: WhyDidYouRenderOptions
20
): typeof React;
21
```
22
23
**Usage Examples:**
24
25
```javascript
26
import React from 'react';
27
import whyDidYouRender from '@welldone-software/why-did-you-render';
28
29
// Basic initialization
30
whyDidYouRender(React);
31
32
// With configuration options
33
whyDidYouRender(React, {
34
trackAllPureComponents: true,
35
trackHooks: true,
36
logOwnerReasons: true,
37
include: [/^MyComponent/],
38
exclude: [/^ThirdParty/]
39
});
40
```
41
42
**TypeScript Setup:**
43
44
For TypeScript projects, add the type reference directive at the top of your setup file:
45
46
```typescript
47
/// <reference types="@welldone-software/why-did-you-render" />
48
49
import React from 'react';
50
import whyDidYouRender from '@welldone-software/why-did-you-render';
51
52
if (process.env.NODE_ENV === 'development') {
53
whyDidYouRender(React, {
54
trackAllPureComponents: true
55
});
56
}
57
```
58
59
**React Native Setup:**
60
61
For React Native applications, setup varies depending on your workflow:
62
63
```javascript
64
// React Native Bare Workflow
65
// babel.config.js
66
module.exports = {
67
presets: ['module:metro-react-native-babel-preset'],
68
69
env: {
70
development: {
71
plugins: [['@babel/plugin-transform-react-jsx', {
72
runtime: 'automatic',
73
development: process.env.NODE_ENV === 'development',
74
importSource: '@welldone-software/why-did-you-render',
75
}]],
76
},
77
},
78
};
79
80
// wdyr.js setup file
81
import React from 'react';
82
83
if (__DEV__) {
84
const whyDidYouRender = require('@welldone-software/why-did-you-render');
85
whyDidYouRender(React, {
86
trackAllPureComponents: true,
87
trackHooks: true
88
});
89
}
90
```
91
92
```javascript
93
// Expo Managed Workflow
94
// babel.config.js
95
module.exports = function (api) {
96
api.cache(true);
97
return {
98
presets: [
99
[
100
"babel-preset-expo",
101
{
102
jsxImportSource: "@welldone-software/why-did-you-render",
103
},
104
],
105
],
106
};
107
};
108
```
109
110
### Static Properties
111
112
The main function includes several static properties for advanced usage:
113
114
```typescript { .api }
115
/**
116
* Default notification handler for re-render events
117
* @param updateInfo - Information about the component update
118
*/
119
whyDidYouRender.defaultNotifier: (updateInfo: UpdateInfo) => void;
120
121
/**
122
* Internal store containing React instance, options, and tracking data
123
*/
124
whyDidYouRender.wdyrStore: WdyrStore;
125
126
/**
127
* Stores owner component data for render tracking
128
* @param element - React element to store owner data for
129
*/
130
whyDidYouRender.storeOwnerData: (element: React.Element) => void;
131
132
/**
133
* Gets the WDYR-patched version of a component type
134
* @param origType - Original component type
135
* @returns Patched component type or null if not trackable
136
*/
137
whyDidYouRender.getWDYRType: (origType: React.ComponentType) => React.ComponentType | null;
138
139
/**
140
* Gets the current owner component during rendering
141
* @returns Current owner component or null
142
*/
143
whyDidYouRender.getCurrentOwner: () => React.Component | null;
144
145
/**
146
* Creates a default notifier with hot reload handling
147
* @param hotReloadBufferMs - Buffer time in milliseconds to ignore updates after hot reload
148
* @returns Default notifier function with hot reload support
149
*/
150
whyDidYouRender.createDefaultNotifier: (hotReloadBufferMs?: number) => Notifier;
151
```
152
153
### Configuration Options
154
155
Comprehensive configuration interface for controlling tracking behavior:
156
157
```typescript { .api }
158
interface WhyDidYouRenderOptions {
159
/** Array of RegExp patterns to include - only components matching these patterns will be tracked */
160
include?: RegExp[];
161
162
/** Array of RegExp patterns to exclude - components matching these patterns will not be tracked */
163
exclude?: RegExp[];
164
165
/** Whether to automatically track all React.PureComponent and React.memo components */
166
trackAllPureComponents?: boolean;
167
168
/** Whether to track React hooks for state changes */
169
trackHooks?: boolean;
170
171
/** Whether to log information about the component that caused the re-render */
172
logOwnerReasons?: boolean;
173
174
/** Additional hooks to track beyond the built-in ones */
175
trackExtraHooks?: Array<ExtraHookToTrack>;
176
177
/** Whether to log even when values are different (normally only logs when values are the same) */
178
logOnDifferentValues?: boolean;
179
180
/** Buffer time in milliseconds to prevent logging during hot reload */
181
hotReloadBufferMs?: number;
182
183
/** Use console.log instead of console.group for simpler output */
184
onlyLogs?: boolean;
185
186
/** Use console.groupCollapsed instead of console.group for collapsed output */
187
collapseGroups?: boolean;
188
189
/** Color for component names in console output */
190
titleColor?: string;
191
192
/** Color for diff property names in console output */
193
diffNameColor?: string;
194
195
/** Color for diff property paths in console output */
196
diffPathColor?: string;
197
198
/** Background color for console text */
199
textBackgroundColor?: string;
200
201
/** Custom notification handler to replace the default console logger */
202
notifier?: Notifier;
203
204
/** Custom name to use in notifications */
205
customName?: string;
206
207
/** Function to extract additional data from React elements for owner tracking */
208
getAdditionalOwnerData?: (element: React.Element) => any;
209
}
210
```
211
212
### Component Integration
213
214
Components can be individually configured for tracking using the `whyDidYouRender` property:
215
216
```typescript { .api }
217
type WhyDidYouRenderComponentMember = WhyDidYouRenderOptions | boolean;
218
```
219
220
**Usage Examples:**
221
222
```javascript
223
// Enable tracking for a specific component
224
const MyComponent = React.memo(({ data }) => {
225
return <div>{data.name}</div>;
226
});
227
MyComponent.whyDidYouRender = true;
228
229
// Configure tracking options for a specific component
230
const AnotherComponent = React.memo(({ items }) => {
231
return <ul>{items.map(item => <li key={item.id}>{item.name}</li>)}</ul>;
232
});
233
AnotherComponent.whyDidYouRender = {
234
logOnDifferentValues: true,
235
customName: 'ItemList'
236
};
237
```
238
239
### Library Reversion
240
241
The library provides a way to remove its patches and restore React to its original state:
242
243
```typescript { .api }
244
/**
245
* Reverts all Why Did You Render patches and restores React to original state
246
* This function is added to React after initialization
247
*/
248
React.__REVERT_WHY_DID_YOU_RENDER__(): void;
249
```
250
251
**Usage Example:**
252
253
```javascript
254
// Initialize WDYR
255
whyDidYouRender(React, options);
256
257
// Later, revert all changes
258
React.__REVERT_WHY_DID_YOU_RENDER__();
259
```
260
261
## Internal Types
262
263
```typescript { .api }
264
interface WdyrStore {
265
React: typeof React;
266
options: WhyDidYouRenderOptions;
267
origCreateElement: typeof React.createElement;
268
origCreateFactory: typeof React.createFactory;
269
origCloneElement: typeof React.cloneElement;
270
componentsMap: WeakMap<any, any>;
271
ownerDataMap: WeakMap<any, any>;
272
hooksInfoForCurrentRender: WeakMap<any, any>;
273
ownerBeforeElementCreation: any;
274
}
275
```