main
js 150 lines 3.83 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @flow
8 */
9
10 import {getVersionedRenderImplementation} from './utils';
11
12 describe('Profiler change descriptions', () => {
13 let React;
14 let store;
15 let utils;
16
17 beforeEach(() => {
18 utils = require('./utils');
19 utils.beforeEachProfiling();
20
21 store = global.store;
22 store.collapseNodesByDefault = false;
23 store.recordChangeDescriptions = true;
24
25 React = require('react');
26 });
27
28 const {render} = getVersionedRenderImplementation();
29
30 // @reactVersion >=18.0
31 it('should identify useContext as the cause for a re-render', () => {
32 const Context = React.createContext(0);
33
34 function Child() {
35 const context = React.useContext(Context);
36 return context;
37 }
38
39 function areEqual() {
40 return true;
41 }
42
43 const MemoizedChild = React.memo(Child, areEqual);
44 const ForwardRefChild = React.forwardRef(
45 function RefForwardingComponent(props, ref) {
46 return <Child />;
47 },
48 );
49
50 let forceUpdate = null;
51
52 const App = function App() {
53 const [val, dispatch] = React.useReducer(x => x + 1, 0);
54
55 forceUpdate = dispatch;
56
57 return (
58 <Context.Provider value={val}>
59 <Child />
60 <MemoizedChild />
61 <ForwardRefChild />
62 </Context.Provider>
63 );
64 };
65
66 utils.act(() => store.profilerStore.startProfiling());
67 utils.act(() => render(<App />));
68 utils.act(() => forceUpdate());
69 utils.act(() => store.profilerStore.stopProfiling());
70
71 const rootID = store.roots[0];
72 const commitData = store.profilerStore.getCommitData(rootID, 1);
73
74 expect(store).toMatchInlineSnapshot(`
75 [root]
76 ▾ <App>
77 ▾ <Context.Provider>
78 <Child>
79 ▾ <Child> [Memo]
80 <Child>
81 ▾ <RefForwardingComponent> [ForwardRef]
82 <Child>
83 `);
84
85 let element = store.getElementAtIndex(2);
86 expect(element.displayName).toBe('Child');
87 expect(element.hocDisplayNames).toBeNull();
88 expect(commitData.changeDescriptions.get(element.id))
89 .toMatchInlineSnapshot(`
90 {
91 "context": true,
92 "didHooksChange": false,
93 "hooks": [],
94 "isFirstMount": false,
95 "props": [],
96 "state": null,
97 }
98 `);
99
100 element = store.getElementAtIndex(3);
101 expect(element.displayName).toBe('Child');
102 expect(element.hocDisplayNames).toEqual(['Memo']);
103 expect(commitData.changeDescriptions.get(element.id)).toBeUndefined();
104
105 element = store.getElementAtIndex(4);
106 expect(element.displayName).toBe('Child');
107 expect(element.hocDisplayNames).toBeNull();
108 expect(commitData.changeDescriptions.get(element.id))
109 .toMatchInlineSnapshot(`
110 {
111 "context": true,
112 "didHooksChange": false,
113 "hooks": [],
114 "isFirstMount": false,
115 "props": [],
116 "state": null,
117 }
118 `);
119
120 element = store.getElementAtIndex(5);
121 expect(element.displayName).toBe('RefForwardingComponent');
122 expect(element.hocDisplayNames).toEqual(['ForwardRef']);
123 expect(commitData.changeDescriptions.get(element.id))
124 .toMatchInlineSnapshot(`
125 {
126 "context": false,
127 "didHooksChange": false,
128 "hooks": [],
129 "isFirstMount": false,
130 "props": [],
131 "state": null,
132 }
133 `);
134
135 element = store.getElementAtIndex(6);
136 expect(element.displayName).toBe('Child');
137 expect(element.hocDisplayNames).toBeNull();
138 expect(commitData.changeDescriptions.get(element.id))
139 .toMatchInlineSnapshot(`
140 {
141 "context": true,
142 "didHooksChange": false,
143 "hooks": [],
144 "isFirstMount": false,
145 "props": [],
146 "state": null,
147 }
148 `);
149 });
150 });