1209
}
1210
});
1211
1212
+ // @reactVersion >= 19.0
1213
+ it('should detect context changes or lack of changes with conditional use()', () => {
1214
+ const ContextA = React.createContext(0);
1215
+ const ContextB = React.createContext(1);
1216
+ let setState = null;
1217
+
1218
+ const Component = () => {
1219
+ // These hooks may change and initiate re-renders.
1220
+ let state;
1221
+ [state, setState] = React.useState('abc');
1222
+
1223
+ let result = state;
1224
+
1225
+ if (state.includes('a')) {
1226
+ result += React.use(ContextA);
1227
+ }
1228
+
1229
+ result += React.use(ContextB);
1230
+
1231
+ return result;
1232
+ };
1233
+
1234
+ utils.act(() =>
1235
+ render(
1236
+ <ContextA.Provider value={1}>
1237
+ <ContextB.Provider value={1}>
1238
+ <Component />
1239
+ </ContextB.Provider>
1240
+ </ContextA.Provider>,
1241
+ ),
1242
+ );
1243
+
1244
+ utils.act(() => store.profilerStore.startProfiling());
1245
+
1246
+ // First render changes Context.
1247
+ utils.act(() =>
1248
+ render(
1249
+ <ContextA.Provider value={0}>
1250
+ <ContextB.Provider value={1}>
1251
+ <Component />
1252
+ </ContextB.Provider>
1253
+ </ContextA.Provider>,
1254
+ ),
1255
+ );
1256
+
1257
+ // Second render has no changed Context, only changed state.
1258
+ utils.act(() => setState('def'));
1259
+
1260
+ utils.act(() => store.profilerStore.stopProfiling());
1261
+
1262
+ const rootID = store.roots[0];
1263
+
1264
+ const changeDescriptions = store.profilerStore
1265
+ .getDataForRoot(rootID)
1266
+ .commitData.map(commitData => commitData.changeDescriptions);
1267
+ expect(changeDescriptions).toHaveLength(2);
1268
+
1269
+ // 1st render: Change to Context
1270
+ expect(changeDescriptions[0]).toMatchInlineSnapshot(`
1271
+ Map {
1272
+ 4 => {
1273
+ "context": true,
1274
+ "didHooksChange": false,
1275
+ "hooks": [],
1276
+ "isFirstMount": false,
1277
+ "props": [],
1278
+ "state": null,
1279
+ },
1280
+ }
1281
+ `);
1282
+
1283
+ // 2nd render: Change to State
1284
+ expect(changeDescriptions[1]).toMatchInlineSnapshot(`
1285
+ Map {
1286
+ 4 => {
1287
+ "context": false,
1288
+ "didHooksChange": true,
1289
+ "hooks": [
1290
+ 0,
1291
+ ],
1292
+ "isFirstMount": false,
1293
+ "props": [],
1294
+ "state": null,
1295
+ },
1296
+ }
1297
+ `);
1298
+
1299
+ expect(changeDescriptions).toHaveLength(2);
1300
+
1301
+ // Export and re-import profile data and make sure it is retained.
1302
+ utils.exportImportHelper(bridge, store);
1303
+
1304
+ for (let commitIndex = 0; commitIndex < 2; commitIndex++) {
1305
+ const commitData = store.profilerStore.getCommitData(rootID, commitIndex);
1306
+ expect(commitData.changeDescriptions).toEqual(
1307
+ changeDescriptions[commitIndex],
1308
+ );
1309
+ }
1310
+ });
1311
+
1312
// @reactVersion >= 18.0
1313
it('should calculate durations based on actual children (not filtered children)', () => {
1314
store.componentFilters = [utils.createDisplayNameFilter('^Parent$')];