0
# Why Did You Render
1
2
Why Did You Render is a React development tool that monkey patches React to detect and notify developers about potentially avoidable component re-renders. It tracks pure components (React.PureComponent and React.memo) and custom hooks, analyzing prop and state changes to identify when components re-render with identical values. Works with both React web applications and React Native.
3
4
## Package Information
5
6
- **Package Name**: @welldone-software/why-did-you-render
7
- **Package Type**: npm
8
- **Language**: JavaScript/TypeScript
9
- **Installation**: `npm install @welldone-software/why-did-you-render --save-dev`
10
11
## Core Imports
12
13
```javascript
14
import whyDidYouRender from '@welldone-software/why-did-you-render';
15
```
16
17
For CommonJS:
18
19
```javascript
20
const whyDidYouRender = require('@welldone-software/why-did-you-render');
21
```
22
23
JSX Runtime (for React 19 automatic JSX transformation):
24
25
```javascript
26
// These are handled automatically when configured as importSource
27
import '@welldone-software/why-did-you-render/jsx-runtime';
28
import '@welldone-software/why-did-you-render/jsx-dev-runtime';
29
```
30
31
## Basic Usage
32
33
```javascript
34
import React from 'react';
35
import whyDidYouRender from '@welldone-software/why-did-you-render';
36
37
// Initialize the library (typically in your app's entry point)
38
if (process.env.NODE_ENV === 'development') {
39
whyDidYouRender(React, {
40
trackAllPureComponents: true,
41
trackHooks: true,
42
logOwnerReasons: true
43
});
44
}
45
46
// Your existing React components will now be tracked
47
const MyComponent = React.memo(({ name, age }) => {
48
return <div>{name} is {age} years old</div>;
49
});
50
51
// The component will be automatically tracked for re-renders
52
export default MyComponent;
53
```
54
55
**React Native Usage:**
56
57
```javascript
58
import React from 'react';
59
import whyDidYouRender from '@welldone-software/why-did-you-render';
60
61
// For React Native, use __DEV__ instead of process.env.NODE_ENV
62
if (__DEV__) {
63
whyDidYouRender(React, {
64
trackAllPureComponents: true,
65
trackHooks: true,
66
logOwnerReasons: true
67
});
68
}
69
```
70
71
## JSX Runtime Integration
72
73
For React 19 with automatic JSX transformation, configure Babel to use the library's JSX runtime:
74
75
```javascript
76
// babel.config.js
77
['@babel/preset-react', {
78
runtime: 'automatic',
79
development: process.env.NODE_ENV === 'development',
80
importSource: '@welldone-software/why-did-you-render',
81
}]
82
```
83
84
## Architecture
85
86
Why Did You Render is built around several key components:
87
88
- **Main Function**: The `whyDidYouRender` function that patches React to enable tracking
89
- **Component Patching**: Automatic wrapping of components to monitor re-renders
90
- **Hook Tracking**: Optional monitoring of React hooks for state changes
91
- **Notification System**: Configurable output system for re-render notifications
92
- **JSX Runtime**: Enhanced JSX transformation for seamless integration
93
94
## Capabilities
95
96
### Core Library Setup
97
98
Main function to initialize Why Did You Render with React and configure tracking options.
99
100
```typescript { .api }
101
function whyDidYouRender(
102
React: typeof React,
103
options?: WhyDidYouRenderOptions
104
): typeof React;
105
```
106
107
[Core Setup and Configuration](./core-setup.md)
108
109
### Component Tracking
110
111
Built-in component tracking and notification system with detailed re-render analysis.
112
113
```typescript { .api }
114
interface UpdateInfo {
115
Component: React.Component;
116
displayName: string;
117
prevProps: any;
118
prevState: any;
119
nextProps: any;
120
nextState: any;
121
prevHookResult: any;
122
nextHookResult: any;
123
reason: ReasonForUpdate;
124
options: WhyDidYouRenderOptions;
125
hookName?: string;
126
}
127
128
type Notifier = (updateInfo: UpdateInfo) => void;
129
```
130
131
[Component Tracking and Notifications](./component-tracking.md)
132
133
### Hook Integration
134
135
Advanced hook tracking for monitoring React hooks like useState, useReducer, and custom hooks.
136
137
```typescript { .api }
138
interface HookDifference {
139
pathString: string;
140
diffType: string;
141
prevValue: any;
142
nextValue: any;
143
}
144
145
type ExtraHookToTrack = [any, string];
146
```
147
148
[Hook Tracking](./hook-tracking.md)
149
150
### JSX Runtime Integration
151
152
Enhanced JSX transformation for React 19 automatic JSX runtime with seamless WDYR integration.
153
154
```typescript { .api }
155
/**
156
* Enhanced jsxDEV function that wraps React's jsx-dev-runtime
157
* Automatically applies WDYR tracking to components during JSX transformation
158
*/
159
declare const jsxDEV: typeof import('react/jsx-dev-runtime').jsxDEV;
160
```
161
162
[JSX Runtime Integration](./jsx-runtime.md)
163
164
## Type Definitions
165
166
```typescript { .api }
167
interface WhyDidYouRenderOptions {
168
include?: RegExp[];
169
exclude?: RegExp[];
170
trackAllPureComponents?: boolean;
171
trackHooks?: boolean;
172
logOwnerReasons?: boolean;
173
trackExtraHooks?: Array<ExtraHookToTrack>;
174
logOnDifferentValues?: boolean;
175
hotReloadBufferMs?: number;
176
onlyLogs?: boolean;
177
collapseGroups?: boolean;
178
titleColor?: string;
179
diffNameColor?: string;
180
diffPathColor?: string;
181
textBackgroundColor?: string;
182
notifier?: Notifier;
183
getAdditionalOwnerData?: (element: React.Element) => any;
184
}
185
186
interface ReasonForUpdate {
187
hookDifferences: HookDifference[];
188
propsDifferences: boolean;
189
stateDifferences: boolean;
190
ownerDifferences?: {
191
propsDifferences?: HookDifference[];
192
stateDifferences?: HookDifference[];
193
hookDifferences?: Array<{
194
hookName: string;
195
differences: HookDifference[];
196
}>;
197
};
198
}
199
200
type WhyDidYouRenderComponentMember = WhyDidYouRenderOptions | boolean;
201
202
interface WdyrStore {
203
React: typeof React;
204
options: WhyDidYouRenderOptions;
205
origCreateElement: typeof React.createElement;
206
origCreateFactory: typeof React.createFactory;
207
origCloneElement: typeof React.cloneElement;
208
componentsMap: WeakMap<any, any>;
209
ownerDataMap: WeakMap<any, any>;
210
hooksInfoForCurrentRender: WeakMap<any, any>;
211
ownerBeforeElementCreation: any;
212
}
213
```
214
215
**React Module Augmentation:**
216
217
The library extends React component interfaces to support the `whyDidYouRender` property:
218
219
```typescript { .api }
220
declare module 'react' {
221
interface FunctionComponent<P = {}> {
222
whyDidYouRender?: WhyDidYouRenderComponentMember;
223
}
224
225
interface VoidFunctionComponent<P = {}> {
226
whyDidYouRender?: WhyDidYouRenderComponentMember;
227
}
228
229
interface ExoticComponent<P = {}> {
230
whyDidYouRender?: WhyDidYouRenderComponentMember;
231
}
232
233
namespace Component {
234
const whyDidYouRender: WhyDidYouRenderComponentMember;
235
}
236
}
237
```