@samitouri / QOS-React-2 / commits / a8f5e77b92

Remove invokeGuardedCallback from commit phase (#21666)

* Remove invokeGuardedCallback from commit phase * Sync fork

Dan Abramov committed Jun 14, 2021 at 21:45 UTC a8f5e77b921c890c215fb1c7e24a06f38598deb1
4 files changed +172 -636
packages/react-dom/src/__tests__/ReactDOM-test.js
-43
@@ -408,49 +408,6 @@ describe('ReactDOM', () => {
408 }
409 });
410
411 - it('throws in DEV if jsdom is destroyed by the time setState() is called', () => {
412 - class App extends React.Component {
413 - state = {x: 1};
414 - componentDidUpdate() {}
415 - render() {
416 - return <div />;
417 - }
418 - }
419 - const container = document.createElement('div');
420 - const instance = ReactDOM.render(<App />, container);
421 - const documentDescriptor = Object.getOwnPropertyDescriptor(
422 - global,
423 - 'document',
424 - );
425 - try {
426 - // Emulate jsdom environment cleanup.
427 - // This is roughly what happens if the test finished and then
428 - // an asynchronous callback tried to setState() after this.
429 - delete global.document;
430 -
431 - // The error we're interested in is thrown by invokeGuardedCallback, which
432 - // in DEV is used 1) to replay a failed begin phase, or 2) when calling
433 - // lifecycle methods. We're triggering the second case here.
434 - const fn = () => instance.setState({x: 2});
435 - if (__DEV__) {
436 - expect(fn).toThrow(
437 - 'The `document` global was defined when React was initialized, but is not ' +
438 - 'defined anymore. This can happen in a test environment if a component ' +
439 - 'schedules an update from an asynchronous callback, but the test has already ' +
440 - 'finished running. To solve this, you can either unmount the component at ' +
441 - 'the end of your test (and ensure that any asynchronous operations get ' +
442 - 'canceled in `componentWillUnmount`), or you can change the test itself ' +
443 - 'to be asynchronous.',
444 - );
445 - } else {
446 - expect(fn).not.toThrow();
447 - }
448 - } finally {
449 - // Don't break other tests.
450 - Object.defineProperty(global, 'document', documentDescriptor);
451 - }
452 - });
453 -
411 it('reports stacks with re-entrant renderToString() calls on the client', () => {
412 function Child2(props) {
413 return <span ariaTypo3="no">{props.children}</span>;
packages/react-reconciler/src/ReactFiberCommitWork.new.js
+86 -264
@@ -57,11 +57,6 @@ import {
57 OffscreenComponent,
58 LegacyHiddenComponent,
59 } from './ReactWorkTags';
60 -import {
61 - invokeGuardedCallback,
62 - hasCaughtError,
63 - clearCaughtError,
64 -} from 'shared/ReactErrorUtils';
60 import {detachDeletedInstance} from './ReactFiberHostConfig';
61 import {
62 NoFlags,
@@ -189,24 +184,10 @@ function safelyCallCommitHookLayoutEffectListMount(
184 current: Fiber,
185 nearestMountedAncestor: Fiber | null,
186 ) {
192 - if (__DEV__) {
193 - invokeGuardedCallback(
194 - null,
195 - commitHookEffectListMount,
196 - null,
197 - HookLayout,
198 - current,
199 - );
200 - if (hasCaughtError()) {
201 - const unmountError = clearCaughtError();
202 - captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
203 - }
204 - } else {
205 - try {
206 - commitHookEffectListMount(HookLayout, current);
207 - } catch (unmountError) {
208 - captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
209 - }
187 + try {
188 + commitHookEffectListMount(HookLayout, current);
189 + } catch (unmountError) {
190 + captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
191 }
192 }
193
@@ -216,24 +197,10 @@ function safelyCallComponentWillUnmount(
197 nearestMountedAncestor: Fiber | null,
198 instance: any,
199 ) {
219 - if (__DEV__) {
220 - invokeGuardedCallback(
221 - null,
222 - callComponentWillUnmountWithTimer,
223 - null,
224 - current,
225 - instance,
226 - );
227 - if (hasCaughtError()) {
228 - const unmountError = clearCaughtError();
229 - captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
230 - }
231 - } else {
232 - try {
233 - callComponentWillUnmountWithTimer(current, instance);
234 - } catch (unmountError) {
235 - captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
236 - }
200 + try {
201 + callComponentWillUnmountWithTimer(current, instance);
202 + } catch (unmountError) {
203 + captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
204 }
205 }
206
@@ -243,35 +210,19 @@ function safelyCallComponentDidMount(
210 nearestMountedAncestor: Fiber | null,
211 instance: any,
212 ) {
246 - if (__DEV__) {
247 - invokeGuardedCallback(null, instance.componentDidMount, instance);
248 - if (hasCaughtError()) {
249 - const unmountError = clearCaughtError();
250 - captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
251 - }
252 - } else {
253 - try {
254 - instance.componentDidMount();
255 - } catch (unmountError) {
256 - captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
257 - }
213 + try {
214 + instance.componentDidMount();
215 + } catch (unmountError) {
216 + captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
217 }
218 }
219
220 // Capture errors so they don't interrupt mounting.
221 function safelyAttachRef(current: Fiber, nearestMountedAncestor: Fiber | null) {
263 - if (__DEV__) {
264 - invokeGuardedCallback(null, commitAttachRef, null, current);
265 - if (hasCaughtError()) {
266 - const unmountError = clearCaughtError();
267 - captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
268 - }
269 - } else {
270 - try {
271 - commitAttachRef(current);
272 - } catch (unmountError) {
273 - captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
274 - }
222 + try {
223 + commitAttachRef(current);
224 + } catch (unmountError) {
225 + captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
226 }
227 }
228
@@ -279,42 +230,23 @@ function safelyDetachRef(current: Fiber, nearestMountedAncestor: Fiber | null) {
230 const ref = current.ref;
231 if (ref !== null) {
232 if (typeof ref === 'function') {
282 - if (__DEV__) {
233 + try {
234 if (
235 enableProfilerTimer &&
236 enableProfilerCommitHooks &&
237 current.mode & ProfileMode
238 ) {
288 - startLayoutEffectTimer();
289 - invokeGuardedCallback(null, ref, null, null);
290 - recordLayoutEffectDuration(current);
291 - } else {
292 - invokeGuardedCallback(null, ref, null, null);
293 - }
294 -
295 - if (hasCaughtError()) {
296 - const refError = clearCaughtError();
297 - captureCommitPhaseError(current, nearestMountedAncestor, refError);
298 - }
299 - } else {
300 - try {
301 - if (
302 - enableProfilerTimer &&
303 - enableProfilerCommitHooks &&
304 - current.mode & ProfileMode
305 - ) {
306 - try {
307 - startLayoutEffectTimer();
308 - ref(null);
309 - } finally {
310 - recordLayoutEffectDuration(current);
311 - }
312 - } else {
239 + try {
240 + startLayoutEffectTimer();
241 ref(null);
242 + } finally {
243 + recordLayoutEffectDuration(current);
244 }
315 - } catch (refError) {
316 - captureCommitPhaseError(current, nearestMountedAncestor, refError);
245 + } else {
246 + ref(null);
247 }
248 + } catch (error) {
249 + captureCommitPhaseError(current, nearestMountedAncestor, error);
250 }
251 } else {
252 ref.current = null;
@@ -327,18 +259,10 @@ function safelyCallDestroy(
259 nearestMountedAncestor: Fiber | null,
260 destroy: () => void,
261 ) {
330 - if (__DEV__) {
331 - invokeGuardedCallback(null, destroy, null);
332 - if (hasCaughtError()) {
333 - const error = clearCaughtError();
334 - captureCommitPhaseError(current, nearestMountedAncestor, error);
335 - }
336 - } else {
337 - try {
338 - destroy();
339 - } catch (error) {
340 - captureCommitPhaseError(current, nearestMountedAncestor, error);
341 - }
262 + try {
263 + destroy();
264 + } catch (error) {
265 + captureCommitPhaseError(current, nearestMountedAncestor, error);
266 }
267 }
268
@@ -395,26 +319,13 @@ function commitBeforeMutationEffects_begin() {
319 function commitBeforeMutationEffects_complete() {
320 while (nextEffect !== null) {
321 const fiber = nextEffect;
398 - if (__DEV__) {
399 - setCurrentDebugFiberInDEV(fiber);
400 - invokeGuardedCallback(
401 - null,
402 - commitBeforeMutationEffectsOnFiber,
403 - null,
404 - fiber,
405 - );
406 - if (hasCaughtError()) {
407 - const error = clearCaughtError();
408 - captureCommitPhaseError(fiber, fiber.return, error);
409 - }
410 - resetCurrentDebugFiberInDEV();
411 - } else {
412 - try {
413 - commitBeforeMutationEffectsOnFiber(fiber);
414 - } catch (error) {
415 - captureCommitPhaseError(fiber, fiber.return, error);
416 - }
322 + setCurrentDebugFiberInDEV(fiber);
323 + try {
324 + commitBeforeMutationEffectsOnFiber(fiber);
325 + } catch (error) {
326 + captureCommitPhaseError(fiber, fiber.return, error);
327 }
328 + resetCurrentDebugFiberInDEV();
329
330 const sibling = fiber.sibling;
331 if (sibling !== null) {
@@ -2151,25 +2062,10 @@ function commitMutationEffects_begin(root: FiberRoot) {
2062 if (deletions !== null) {
2063 for (let i = 0; i < deletions.length; i++) {
2064 const childToDelete = deletions[i];
2154 - if (__DEV__) {
2155 - invokeGuardedCallback(
2156 - null,
2157 - commitDeletion,
2158 - null,
2159 - root,
2160 - childToDelete,
2161 - fiber,
2162 - );
2163 - if (hasCaughtError()) {
2164 - const error = clearCaughtError();
2165 - captureCommitPhaseError(childToDelete, fiber, error);
2166 - }
2167 - } else {
2168 - try {
2169 - commitDeletion(root, childToDelete, fiber);
2170 - } catch (error) {
2171 - captureCommitPhaseError(childToDelete, fiber, error);
2172 - }
2065 + try {
2066 + commitDeletion(root, childToDelete, fiber);
2067 + } catch (error) {
2068 + captureCommitPhaseError(childToDelete, fiber, error);
2069 }
2070 }
2071 }
@@ -2187,27 +2083,13 @@ function commitMutationEffects_begin(root: FiberRoot) {
2083 function commitMutationEffects_complete(root: FiberRoot) {
2084 while (nextEffect !== null) {
2085 const fiber = nextEffect;
2190 - if (__DEV__) {
2191 - setCurrentDebugFiberInDEV(fiber);
2192 - invokeGuardedCallback(
2193 - null,
2194 - commitMutationEffectsOnFiber,
2195 - null,
2196 - fiber,
2197 - root,
2198 - );
2199 - if (hasCaughtError()) {
2200 - const error = clearCaughtError();
2201 - captureCommitPhaseError(fiber, fiber.return, error);
2202 - }
2203 - resetCurrentDebugFiberInDEV();
2204 - } else {
2205 - try {
2206 - commitMutationEffectsOnFiber(fiber, root);
2207 - } catch (error) {
2208 - captureCommitPhaseError(fiber, fiber.return, error);
2209 - }
2086 + setCurrentDebugFiberInDEV(fiber);
2087 + try {
2088 + commitMutationEffectsOnFiber(fiber, root);
2089 + } catch (error) {
2090 + captureCommitPhaseError(fiber, fiber.return, error);
2091 }
2092 + resetCurrentDebugFiberInDEV();
2093
2094 const sibling = fiber.sibling;
2095 if (sibling !== null) {
@@ -2444,29 +2326,13 @@ function commitLayoutMountEffects_complete(
2326 }
2327 } else if ((fiber.flags & LayoutMask) !== NoFlags) {
2328 const current = fiber.alternate;
2447 - if (__DEV__) {
2448 - setCurrentDebugFiberInDEV(fiber);
2449 - invokeGuardedCallback(
2450 - null,
2451 - commitLayoutEffectOnFiber,
2452 - null,
2453 - root,
2454 - current,
2455 - fiber,
2456 - committedLanes,
2457 - );
2458 - if (hasCaughtError()) {
2459 - const error = clearCaughtError();
2460 - captureCommitPhaseError(fiber, fiber.return, error);
2461 - }
2462 - resetCurrentDebugFiberInDEV();
2463 - } else {
2464 - try {
2465 - commitLayoutEffectOnFiber(root, current, fiber, committedLanes);
2466 - } catch (error) {
2467 - captureCommitPhaseError(fiber, fiber.return, error);
2468 - }
2329 + setCurrentDebugFiberInDEV(fiber);
2330 + try {
2331 + commitLayoutEffectOnFiber(root, current, fiber, committedLanes);
2332 + } catch (error) {
2333 + captureCommitPhaseError(fiber, fiber.return, error);
2334 }
2335 + resetCurrentDebugFiberInDEV();
2336 }
2337
2338 if (fiber === subtreeRoot) {
@@ -2513,27 +2379,13 @@ function commitPassiveMountEffects_complete(
2379 while (nextEffect !== null) {
2380 const fiber = nextEffect;
2381 if ((fiber.flags & Passive) !== NoFlags) {
2516 - if (__DEV__) {
2517 - setCurrentDebugFiberInDEV(fiber);
2518 - invokeGuardedCallback(
2519 - null,
2520 - commitPassiveMountOnFiber,
2521 - null,
2522 - root,
2523 - fiber,
2524 - );
2525 - if (hasCaughtError()) {
2526 - const error = clearCaughtError();
2527 - captureCommitPhaseError(fiber, fiber.return, error);
2528 - }
2529 - resetCurrentDebugFiberInDEV();
2530 - } else {
2531 - try {
2532 - commitPassiveMountOnFiber(root, fiber);
2533 - } catch (error) {
2534 - captureCommitPhaseError(fiber, fiber.return, error);
2535 - }
2382 + setCurrentDebugFiberInDEV(fiber);
2383 + try {
2384 + commitPassiveMountOnFiber(root, fiber);
2385 + } catch (error) {
2386 + captureCommitPhaseError(fiber, fiber.return, error);
2387 }
2388 + resetCurrentDebugFiberInDEV();
2389 }
2390
2391 if (fiber === subtreeRoot) {
@@ -2810,25 +2662,19 @@ function invokeLayoutEffectMountInDEV(fiber: Fiber): void {
2662 case FunctionComponent:
2663 case ForwardRef:
2664 case SimpleMemoComponent: {
2813 - invokeGuardedCallback(
2814 - null,
2815 - commitHookEffectListMount,
2816 - null,
2817 - HookLayout | HookHasEffect,
2818 - fiber,
2819 - );
2820 - if (hasCaughtError()) {
2821 - const mountError = clearCaughtError();
2822 - captureCommitPhaseError(fiber, fiber.return, mountError);
2665 + try {
2666 + commitHookEffectListMount(HookLayout | HookHasEffect, fiber);
2667 + } catch (error) {
2668 + captureCommitPhaseError(fiber, fiber.return, error);
2669 }
2670 break;
2671 }
2672 case ClassComponent: {
2673 const instance = fiber.stateNode;
2828 - invokeGuardedCallback(null, instance.componentDidMount, instance);
2829 - if (hasCaughtError()) {
2830 - const mountError = clearCaughtError();
2831 - captureCommitPhaseError(fiber, fiber.return, mountError);
2674 + try {
2675 + instance.componentDidMount();
2676 + } catch (error) {
2677 + captureCommitPhaseError(fiber, fiber.return, error);
2678 }
2679 break;
2680 }
@@ -2844,16 +2690,10 @@ function invokePassiveEffectMountInDEV(fiber: Fiber): void {
2690 case FunctionComponent:
2691 case ForwardRef:
2692 case SimpleMemoComponent: {
2847 - invokeGuardedCallback(
2848 - null,
2849 - commitHookEffectListMount,
2850 - null,
2851 - HookPassive | HookHasEffect,
2852 - fiber,
2853 - );
2854 - if (hasCaughtError()) {
2855 - const mountError = clearCaughtError();
2856 - captureCommitPhaseError(fiber, fiber.return, mountError);
2693 + try {
2694 + commitHookEffectListMount(HookPassive | HookHasEffect, fiber);
2695 + } catch (error) {
2696 + captureCommitPhaseError(fiber, fiber.return, error);
2697 }
2698 break;
2699 }
@@ -2869,35 +2709,21 @@ function invokeLayoutEffectUnmountInDEV(fiber: Fiber): void {
2709 case FunctionComponent:
2710 case ForwardRef:
2711 case SimpleMemoComponent: {
2872 - invokeGuardedCallback(
2873 - null,
2874 - commitHookEffectListUnmount,
2875 - null,
2876 - HookLayout | HookHasEffect,
2877 - fiber,
2878 - fiber.return,
2879 - );
2880 - if (hasCaughtError()) {
2881 - const unmountError = clearCaughtError();
2882 - captureCommitPhaseError(fiber, fiber.return, unmountError);
2712 + try {
2713 + commitHookEffectListUnmount(
2714 + HookLayout | HookHasEffect,
2715 + fiber,
2716 + fiber.return,
2717 + );
2718 + } catch (error) {
2719 + captureCommitPhaseError(fiber, fiber.return, error);
2720 }
2721 break;
2722 }
2723 case ClassComponent: {
2724 const instance = fiber.stateNode;
2725 if (typeof instance.componentWillUnmount === 'function') {
2889 - invokeGuardedCallback(
2890 - null,
2891 - safelyCallComponentWillUnmount,
2892 - null,
2893 - fiber,
2894 - fiber.return,
2895 - instance,
2896 - );
2897 - if (hasCaughtError()) {
2898 - const unmountError = clearCaughtError();
2899 - captureCommitPhaseError(fiber, fiber.return, unmountError);
2900 - }
2726 + safelyCallComponentWillUnmount(fiber, fiber.return, instance);
2727 }
2728 break;
2729 }
@@ -2913,19 +2739,15 @@ function invokePassiveEffectUnmountInDEV(fiber: Fiber): void {
2739 case FunctionComponent:
2740 case ForwardRef:
2741 case SimpleMemoComponent: {
2916 - invokeGuardedCallback(
2917 - null,
2918 - commitHookEffectListUnmount,
2919 - null,
2920 - HookPassive | HookHasEffect,
2921 - fiber,
2922 - fiber.return,
2923 - );
2924 - if (hasCaughtError()) {
2925 - const unmountError = clearCaughtError();
2926 - captureCommitPhaseError(fiber, fiber.return, unmountError);
2742 + try {
2743 + commitHookEffectListUnmount(
2744 + HookPassive | HookHasEffect,
2745 + fiber,
2746 + fiber.return,
2747 + );
2748 + } catch (error) {
2749 + captureCommitPhaseError(fiber, fiber.return, error);
2750 }
2928 - break;
2751 }
2752 }
2753 }
packages/react-reconciler/src/ReactFiberCommitWork.old.js
+86 -264
@@ -57,11 +57,6 @@ import {
57 OffscreenComponent,
58 LegacyHiddenComponent,
59 } from './ReactWorkTags';
60 -import {
61 - invokeGuardedCallback,
62 - hasCaughtError,
63 - clearCaughtError,
64 -} from 'shared/ReactErrorUtils';
60 import {detachDeletedInstance} from './ReactFiberHostConfig';
61 import {
62 NoFlags,
@@ -189,24 +184,10 @@ function safelyCallCommitHookLayoutEffectListMount(
184 current: Fiber,
185 nearestMountedAncestor: Fiber | null,
186 ) {
192 - if (__DEV__) {
193 - invokeGuardedCallback(
194 - null,
195 - commitHookEffectListMount,
196 - null,
197 - HookLayout,
198 - current,
199 - );
200 - if (hasCaughtError()) {
201 - const unmountError = clearCaughtError();
202 - captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
203 - }
204 - } else {
205 - try {
206 - commitHookEffectListMount(HookLayout, current);
207 - } catch (unmountError) {
208 - captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
209 - }
187 + try {
188 + commitHookEffectListMount(HookLayout, current);
189 + } catch (unmountError) {
190 + captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
191 }
192 }
193
@@ -216,24 +197,10 @@ function safelyCallComponentWillUnmount(
197 nearestMountedAncestor: Fiber | null,
198 instance: any,
199 ) {
219 - if (__DEV__) {
220 - invokeGuardedCallback(
221 - null,
222 - callComponentWillUnmountWithTimer,
223 - null,
224 - current,
225 - instance,
226 - );
227 - if (hasCaughtError()) {
228 - const unmountError = clearCaughtError();
229 - captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
230 - }
231 - } else {
232 - try {
233 - callComponentWillUnmountWithTimer(current, instance);
234 - } catch (unmountError) {
235 - captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
236 - }
200 + try {
201 + callComponentWillUnmountWithTimer(current, instance);
202 + } catch (unmountError) {
203 + captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
204 }
205 }
206
@@ -243,35 +210,19 @@ function safelyCallComponentDidMount(
210 nearestMountedAncestor: Fiber | null,
211 instance: any,
212 ) {
246 - if (__DEV__) {
247 - invokeGuardedCallback(null, instance.componentDidMount, instance);
248 - if (hasCaughtError()) {
249 - const unmountError = clearCaughtError();
250 - captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
251 - }
252 - } else {
253 - try {
254 - instance.componentDidMount();
255 - } catch (unmountError) {
256 - captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
257 - }
213 + try {
214 + instance.componentDidMount();
215 + } catch (unmountError) {
216 + captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
217 }
218 }
219
220 // Capture errors so they don't interrupt mounting.
221 function safelyAttachRef(current: Fiber, nearestMountedAncestor: Fiber | null) {
263 - if (__DEV__) {
264 - invokeGuardedCallback(null, commitAttachRef, null, current);
265 - if (hasCaughtError()) {
266 - const unmountError = clearCaughtError();
267 - captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
268 - }
269 - } else {
270 - try {
271 - commitAttachRef(current);
272 - } catch (unmountError) {
273 - captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
274 - }
222 + try {
223 + commitAttachRef(current);
224 + } catch (unmountError) {
225 + captureCommitPhaseError(current, nearestMountedAncestor, unmountError);
226 }
227 }
228
@@ -279,42 +230,23 @@ function safelyDetachRef(current: Fiber, nearestMountedAncestor: Fiber | null) {
230 const ref = current.ref;
231 if (ref !== null) {
232 if (typeof ref === 'function') {
282 - if (__DEV__) {
233 + try {
234 if (
235 enableProfilerTimer &&
236 enableProfilerCommitHooks &&
237 current.mode & ProfileMode
238 ) {
288 - startLayoutEffectTimer();
289 - invokeGuardedCallback(null, ref, null, null);
290 - recordLayoutEffectDuration(current);
291 - } else {
292 - invokeGuardedCallback(null, ref, null, null);
293 - }
294 -
295 - if (hasCaughtError()) {
296 - const refError = clearCaughtError();
297 - captureCommitPhaseError(current, nearestMountedAncestor, refError);
298 - }
299 - } else {
300 - try {
301 - if (
302 - enableProfilerTimer &&
303 - enableProfilerCommitHooks &&
304 - current.mode & ProfileMode
305 - ) {
306 - try {
307 - startLayoutEffectTimer();
308 - ref(null);
309 - } finally {
310 - recordLayoutEffectDuration(current);
311 - }
312 - } else {
239 + try {
240 + startLayoutEffectTimer();
241 ref(null);
242 + } finally {
243 + recordLayoutEffectDuration(current);
244 }
315 - } catch (refError) {
316 - captureCommitPhaseError(current, nearestMountedAncestor, refError);
245 + } else {
246 + ref(null);
247 }
248 + } catch (error) {
249 + captureCommitPhaseError(current, nearestMountedAncestor, error);
250 }
251 } else {
252 ref.current = null;
@@ -327,18 +259,10 @@ function safelyCallDestroy(
259 nearestMountedAncestor: Fiber | null,
260 destroy: () => void,
261 ) {
330 - if (__DEV__) {
331 - invokeGuardedCallback(null, destroy, null);
332 - if (hasCaughtError()) {
333 - const error = clearCaughtError();
334 - captureCommitPhaseError(current, nearestMountedAncestor, error);
335 - }
336 - } else {
337 - try {
338 - destroy();
339 - } catch (error) {
340 - captureCommitPhaseError(current, nearestMountedAncestor, error);
341 - }
262 + try {
263 + destroy();
264 + } catch (error) {
265 + captureCommitPhaseError(current, nearestMountedAncestor, error);
266 }
267 }
268
@@ -395,26 +319,13 @@ function commitBeforeMutationEffects_begin() {
319 function commitBeforeMutationEffects_complete() {
320 while (nextEffect !== null) {
321 const fiber = nextEffect;
398 - if (__DEV__) {
399 - setCurrentDebugFiberInDEV(fiber);
400 - invokeGuardedCallback(
401 - null,
402 - commitBeforeMutationEffectsOnFiber,
403 - null,
404 - fiber,
405 - );
406 - if (hasCaughtError()) {
407 - const error = clearCaughtError();
408 - captureCommitPhaseError(fiber, fiber.return, error);
409 - }
410 - resetCurrentDebugFiberInDEV();
411 - } else {
412 - try {
413 - commitBeforeMutationEffectsOnFiber(fiber);
414 - } catch (error) {
415 - captureCommitPhaseError(fiber, fiber.return, error);
416 - }
322 + setCurrentDebugFiberInDEV(fiber);
323 + try {
324 + commitBeforeMutationEffectsOnFiber(fiber);
325 + } catch (error) {
326 + captureCommitPhaseError(fiber, fiber.return, error);
327 }
328 + resetCurrentDebugFiberInDEV();
329
330 const sibling = fiber.sibling;
331 if (sibling !== null) {
@@ -2151,25 +2062,10 @@ function commitMutationEffects_begin(root: FiberRoot) {
2062 if (deletions !== null) {
2063 for (let i = 0; i < deletions.length; i++) {
2064 const childToDelete = deletions[i];
2154 - if (__DEV__) {
2155 - invokeGuardedCallback(
2156 - null,
2157 - commitDeletion,
2158 - null,
2159 - root,
2160 - childToDelete,
2161 - fiber,
2162 - );
2163 - if (hasCaughtError()) {
2164 - const error = clearCaughtError();
2165 - captureCommitPhaseError(childToDelete, fiber, error);
2166 - }
2167 - } else {
2168 - try {
2169 - commitDeletion(root, childToDelete, fiber);
2170 - } catch (error) {
2171 - captureCommitPhaseError(childToDelete, fiber, error);
2172 - }
2065 + try {
2066 + commitDeletion(root, childToDelete, fiber);
2067 + } catch (error) {
2068 + captureCommitPhaseError(childToDelete, fiber, error);
2069 }
2070 }
2071 }
@@ -2187,27 +2083,13 @@ function commitMutationEffects_begin(root: FiberRoot) {
2083 function commitMutationEffects_complete(root: FiberRoot) {
2084 while (nextEffect !== null) {
2085 const fiber = nextEffect;
2190 - if (__DEV__) {
2191 - setCurrentDebugFiberInDEV(fiber);
2192 - invokeGuardedCallback(
2193 - null,
2194 - commitMutationEffectsOnFiber,
2195 - null,
2196 - fiber,
2197 - root,
2198 - );
2199 - if (hasCaughtError()) {
2200 - const error = clearCaughtError();
2201 - captureCommitPhaseError(fiber, fiber.return, error);
2202 - }
2203 - resetCurrentDebugFiberInDEV();
2204 - } else {
2205 - try {
2206 - commitMutationEffectsOnFiber(fiber, root);
2207 - } catch (error) {
2208 - captureCommitPhaseError(fiber, fiber.return, error);
2209 - }
2086 + setCurrentDebugFiberInDEV(fiber);
2087 + try {
2088 + commitMutationEffectsOnFiber(fiber, root);
2089 + } catch (error) {
2090 + captureCommitPhaseError(fiber, fiber.return, error);
2091 }
2092 + resetCurrentDebugFiberInDEV();
2093
2094 const sibling = fiber.sibling;
2095 if (sibling !== null) {
@@ -2444,29 +2326,13 @@ function commitLayoutMountEffects_complete(
2326 }
2327 } else if ((fiber.flags & LayoutMask) !== NoFlags) {
2328 const current = fiber.alternate;
2447 - if (__DEV__) {
2448 - setCurrentDebugFiberInDEV(fiber);
2449 - invokeGuardedCallback(
2450 - null,
2451 - commitLayoutEffectOnFiber,
2452 - null,
2453 - root,
2454 - current,
2455 - fiber,
2456 - committedLanes,
2457 - );
2458 - if (hasCaughtError()) {
2459 - const error = clearCaughtError();
2460 - captureCommitPhaseError(fiber, fiber.return, error);
2461 - }
2462 - resetCurrentDebugFiberInDEV();
2463 - } else {
2464 - try {
2465 - commitLayoutEffectOnFiber(root, current, fiber, committedLanes);
2466 - } catch (error) {
2467 - captureCommitPhaseError(fiber, fiber.return, error);
2468 - }
2329 + setCurrentDebugFiberInDEV(fiber);
2330 + try {
2331 + commitLayoutEffectOnFiber(root, current, fiber, committedLanes);
2332 + } catch (error) {
2333 + captureCommitPhaseError(fiber, fiber.return, error);
2334 }
2335 + resetCurrentDebugFiberInDEV();
2336 }
2337
2338 if (fiber === subtreeRoot) {
@@ -2513,27 +2379,13 @@ function commitPassiveMountEffects_complete(
2379 while (nextEffect !== null) {
2380 const fiber = nextEffect;
2381 if ((fiber.flags & Passive) !== NoFlags) {
2516 - if (__DEV__) {
2517 - setCurrentDebugFiberInDEV(fiber);
2518 - invokeGuardedCallback(
2519 - null,
2520 - commitPassiveMountOnFiber,
2521 - null,
2522 - root,
2523 - fiber,
2524 - );
2525 - if (hasCaughtError()) {
2526 - const error = clearCaughtError();
2527 - captureCommitPhaseError(fiber, fiber.return, error);
2528 - }
2529 - resetCurrentDebugFiberInDEV();
2530 - } else {
2531 - try {
2532 - commitPassiveMountOnFiber(root, fiber);
2533 - } catch (error) {
2534 - captureCommitPhaseError(fiber, fiber.return, error);
2535 - }
2382 + setCurrentDebugFiberInDEV(fiber);
2383 + try {
2384 + commitPassiveMountOnFiber(root, fiber);
2385 + } catch (error) {
2386 + captureCommitPhaseError(fiber, fiber.return, error);
2387 }
2388 + resetCurrentDebugFiberInDEV();
2389 }
2390
2391 if (fiber === subtreeRoot) {
@@ -2810,25 +2662,19 @@ function invokeLayoutEffectMountInDEV(fiber: Fiber): void {
2662 case FunctionComponent:
2663 case ForwardRef:
2664 case SimpleMemoComponent: {
2813 - invokeGuardedCallback(
2814 - null,
2815 - commitHookEffectListMount,
2816 - null,
2817 - HookLayout | HookHasEffect,
2818 - fiber,
2819 - );
2820 - if (hasCaughtError()) {
2821 - const mountError = clearCaughtError();
2822 - captureCommitPhaseError(fiber, fiber.return, mountError);
2665 + try {
2666 + commitHookEffectListMount(HookLayout | HookHasEffect, fiber);
2667 + } catch (error) {
2668 + captureCommitPhaseError(fiber, fiber.return, error);
2669 }
2670 break;
2671 }
2672 case ClassComponent: {
2673 const instance = fiber.stateNode;
2828 - invokeGuardedCallback(null, instance.componentDidMount, instance);
2829 - if (hasCaughtError()) {
2830 - const mountError = clearCaughtError();
2831 - captureCommitPhaseError(fiber, fiber.return, mountError);
2674 + try {
2675 + instance.componentDidMount();
2676 + } catch (error) {
2677 + captureCommitPhaseError(fiber, fiber.return, error);
2678 }
2679 break;
2680 }
@@ -2844,16 +2690,10 @@ function invokePassiveEffectMountInDEV(fiber: Fiber): void {
2690 case FunctionComponent:
2691 case ForwardRef:
2692 case SimpleMemoComponent: {
2847 - invokeGuardedCallback(
2848 - null,
2849 - commitHookEffectListMount,
2850 - null,
2851 - HookPassive | HookHasEffect,
2852 - fiber,
2853 - );
2854 - if (hasCaughtError()) {
2855 - const mountError = clearCaughtError();
2856 - captureCommitPhaseError(fiber, fiber.return, mountError);
2693 + try {
2694 + commitHookEffectListMount(HookPassive | HookHasEffect, fiber);
2695 + } catch (error) {
2696 + captureCommitPhaseError(fiber, fiber.return, error);
2697 }
2698 break;
2699 }
@@ -2869,35 +2709,21 @@ function invokeLayoutEffectUnmountInDEV(fiber: Fiber): void {
2709 case FunctionComponent:
2710 case ForwardRef:
2711 case SimpleMemoComponent: {
2872 - invokeGuardedCallback(
2873 - null,
2874 - commitHookEffectListUnmount,
2875 - null,
2876 - HookLayout | HookHasEffect,
2877 - fiber,
2878 - fiber.return,
2879 - );
2880 - if (hasCaughtError()) {
2881 - const unmountError = clearCaughtError();
2882 - captureCommitPhaseError(fiber, fiber.return, unmountError);
2712 + try {
2713 + commitHookEffectListUnmount(
2714 + HookLayout | HookHasEffect,
2715 + fiber,
2716 + fiber.return,
2717 + );
2718 + } catch (error) {
2719 + captureCommitPhaseError(fiber, fiber.return, error);
2720 }
2721 break;
2722 }
2723 case ClassComponent: {
2724 const instance = fiber.stateNode;
2725 if (typeof instance.componentWillUnmount === 'function') {
2889 - invokeGuardedCallback(
2890 - null,
2891 - safelyCallComponentWillUnmount,
2892 - null,
2893 - fiber,
2894 - fiber.return,
2895 - instance,
2896 - );
2897 - if (hasCaughtError()) {
2898 - const unmountError = clearCaughtError();
2899 - captureCommitPhaseError(fiber, fiber.return, unmountError);
2900 - }
2726 + safelyCallComponentWillUnmount(fiber, fiber.return, instance);
2727 }
2728 break;
2729 }
@@ -2913,19 +2739,15 @@ function invokePassiveEffectUnmountInDEV(fiber: Fiber): void {
2739 case FunctionComponent:
2740 case ForwardRef:
2741 case SimpleMemoComponent: {
2916 - invokeGuardedCallback(
2917 - null,
2918 - commitHookEffectListUnmount,
2919 - null,
2920 - HookPassive | HookHasEffect,
2921 - fiber,
2922 - fiber.return,
2923 - );
2924 - if (hasCaughtError()) {
2925 - const unmountError = clearCaughtError();
2926 - captureCommitPhaseError(fiber, fiber.return, unmountError);
2742 + try {
2743 + commitHookEffectListUnmount(
2744 + HookPassive | HookHasEffect,
2745 + fiber,
2746 + fiber.return,
2747 + );
2748 + } catch (error) {
2749 + captureCommitPhaseError(fiber, fiber.return, error);
2750 }
2928 - break;
2751 }
2752 }
2753 }
packages/react-reconciler/src/__tests__/ReactSuspenseCallback-test.js
-65
@@ -244,69 +244,4 @@ describe('ReactSuspense', () => {
244 expect(ops1).toEqual([]);
245 expect(ops2).toEqual([]);
246 });
247 -
248 - if (__DEV__) {
249 - // @gate www
250 - it('regression test for #16215 that relies on implementation details', async () => {
251 - // Regression test for https://github.com/facebook/react/pull/16215.
252 - // The bug only happens if there's an error earlier in the commit phase.
253 - // The first error is the one that gets thrown, so to observe the later
254 - // error, I've mocked the ReactErrorUtils module.
255 - //
256 - // If this test starts failing because the implementation details change,
257 - // you can probably just delete it. It's not worth the hassle.
258 - jest.resetModules();
259 -
260 - const errors = [];
261 - let hasCaughtError = false;
262 - jest.mock('shared/ReactErrorUtils', () => ({
263 - invokeGuardedCallback(name, fn, context, ...args) {
264 - try {
265 - return fn.call(context, ...args);
266 - } catch (error) {
267 - hasCaughtError = true;
268 - errors.push(error);
269 - }
270 - },
271 - hasCaughtError() {
272 - return hasCaughtError;
273 - },
274 - clearCaughtError() {
275 - hasCaughtError = false;
276 - return errors[errors.length - 1];
277 - },
278 - }));
279 -
280 - React = require('react');
281 - ReactNoop = require('react-noop-renderer');
282 - Scheduler = require('scheduler');
283 -
284 - const {useEffect} = React;
285 - const {PromiseComp} = createThenable();
286 - function App() {
287 - useEffect(() => {
288 - Scheduler.unstable_yieldValue('Passive Effect');
289 - });
290 - return (
291 - <React.Suspense
292 - suspenseCallback={() => {
293 - throw Error('Oops!');
294 - }}
295 - fallback="Loading...">
296 - <PromiseComp />
297 - </React.Suspense>
298 - );
299 - }
300 - const root = ReactNoop.createRoot();
301 - await ReactNoop.act(async () => {
302 - root.render(<App />);
303 - expect(Scheduler).toFlushAndThrow('Oops!');
304 - });
305 -
306 - // Should have only received a single error. Before the bug fix, there was
307 - // also a second error related to the Suspense update queue.
308 - expect(errors.length).toBe(1);
309 - expect(errors[0].message).toEqual('Oops!');
310 - });
311 - }
247 });