Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable getDerivedStateFromError #13746

Merged
merged 10 commits into from Sep 28, 2018

Conversation

Projects
None yet
4 participants
@bvaughn
Copy link
Contributor

bvaughn commented Sep 27, 2018

Commits are split up for easier review:

  • 4ed84b0: Remove the enableGetDerivedStateFromCatch feature flag.
  • cd49672: Copy-paste ReactErrorBoundaries to ReactLegacyErrorBoundaries to preserve tests for legacy componentDidCatch recovery behavior. (We will eventually remove most of these tests when componentDidCatch no longer supports state updates.)
  • 56bbf1c: Update previous ReactErrorBoundaries tests to cover new getDerivedStateFromCatch render-phase behavior and fixed a minor reconciliation bug that testing uncovered.
  • f6fb111: Rename getDerivedStateFromCatch to getDerivedStateFromError.
  • 3df17ba: Add DEV warning if an error boundary specifies only the componentDidCatch lifecycle and does not trigger a state update (because this would swallow the error).
  • Add a test for re-throwing an error from getDerivedStateFromError to ensure that error bubbling works as expected.

(The only commits that aren't just rote find-and-replace are 56bbf1c and 3df17ba.)

@sizebot

This comment has been minimized.

Copy link

sizebot commented Sep 27, 2018

ReactDOM: size: 🔺+0.3%, gzip: 🔺+0.2%

Details of bundled changes.

Comparing: a0733fe...f1171b7

react-dom

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-dom.development.js +0.2% +0.3% 657.45 KB 659.01 KB 153.47 KB 153.9 KB UMD_DEV
react-dom.production.min.js 🔺+0.3% 🔺+0.2% 93.18 KB 93.44 KB 30.31 KB 30.37 KB UMD_PROD
react-dom.development.js +0.2% +0.3% 652.79 KB 654.34 KB 152.09 KB 152.52 KB NODE_DEV
react-dom.production.min.js 🔺+0.3% 🔺+0.2% 93.17 KB 93.44 KB 29.88 KB 29.93 KB NODE_PROD
react-dom-server.browser.development.js -0.1% -0.2% 106.22 KB 106.12 KB 28.26 KB 28.22 KB UMD_DEV
react-dom-server.browser.development.js -0.1% -0.2% 102.35 KB 102.25 KB 27.27 KB 27.22 KB NODE_DEV
react-dom-server.node.development.js -0.1% -0.2% 104.27 KB 104.18 KB 27.83 KB 27.78 KB NODE_DEV
ReactDOM-dev.js +0.3% +0.3% 669.84 KB 671.66 KB 152.73 KB 153.24 KB FB_WWW_DEV
ReactDOM-prod.js 🔺+0.1% -0.0% 287.26 KB 287.49 KB 52.83 KB 52.81 KB FB_WWW_PROD
ReactDOMServer-dev.js -0.1% -0.1% 102.14 KB 102.06 KB 26.67 KB 26.64 KB FB_WWW_DEV
react-dom.profiling.min.js +0.3% +0.2% 96.16 KB 96.43 KB 30.55 KB 30.6 KB NODE_PROFILING
ReactDOM-profiling.js +0.1% -0.0% 294.1 KB 294.4 KB 54.29 KB 54.28 KB FB_WWW_PROFILING
react-dom.profiling.min.js +0.3% +0.2% 96.1 KB 96.37 KB 30.99 KB 31.05 KB UMD_PROFILING

react-art

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-art.development.js +0.3% +0.4% 447.4 KB 448.96 KB 99.87 KB 100.32 KB UMD_DEV
react-art.production.min.js 🔺+0.3% 🔺+0.1% 85.62 KB 85.88 KB 26.18 KB 26.21 KB UMD_PROD
react-art.development.js +0.4% +0.5% 379.17 KB 380.73 KB 82.7 KB 83.15 KB NODE_DEV
react-art.production.min.js 🔺+0.5% 🔺+0.4% 50.58 KB 50.85 KB 15.44 KB 15.5 KB NODE_PROD
ReactART-dev.js +0.5% +0.6% 382.99 KB 384.81 KB 81.16 KB 81.68 KB FB_WWW_DEV
ReactART-prod.js 🔺+0.1% -0.0% 163.09 KB 163.3 KB 27.43 KB 27.42 KB FB_WWW_PROD

react-test-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-test-renderer.development.js +0.4% +0.6% 391.18 KB 392.83 KB 85.25 KB 85.73 KB UMD_DEV
react-test-renderer.production.min.js 🔺+0.5% 🔺+0.3% 51.8 KB 52.06 KB 15.72 KB 15.77 KB UMD_PROD
react-test-renderer.development.js +0.4% +0.6% 386.75 KB 388.4 KB 84.13 KB 84.6 KB NODE_DEV
react-test-renderer.production.min.js 🔺+0.5% 🔺+0.1% 51.52 KB 51.78 KB 15.57 KB 15.59 KB NODE_PROD
ReactTestRenderer-dev.js +0.5% +0.6% 390.72 KB 392.58 KB 82.86 KB 83.39 KB FB_WWW_DEV

react-reconciler

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-reconciler.development.js +0.4% +0.5% 375 KB 376.56 KB 80.81 KB 81.24 KB NODE_DEV
react-reconciler.production.min.js 🔺+0.5% 🔺+0.4% 50.27 KB 50.54 KB 14.99 KB 15.05 KB NODE_PROD
react-reconciler-persistent.development.js +0.4% +0.6% 373.43 KB 375.09 KB 80.17 KB 80.64 KB NODE_DEV
react-reconciler-persistent.production.min.js 🔺+0.5% 🔺+0.4% 50.29 KB 50.55 KB 15 KB 15.06 KB NODE_PROD

react-native-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactNativeRenderer-dev.js +0.4% +0.5% 506.86 KB 508.68 KB 111.66 KB 112.19 KB RN_FB_DEV
ReactNativeRenderer-prod.js 🔺+0.1% -0.0% 218.19 KB 218.39 KB 37.85 KB 37.84 KB RN_FB_PROD
ReactNativeRenderer-dev.js +0.4% +0.5% 506.52 KB 508.37 KB 111.57 KB 112.1 KB RN_OSS_DEV
ReactNativeRenderer-prod.js 🔺+0.4% 🔺+0.3% 207.87 KB 208.68 KB 36.21 KB 36.3 KB RN_OSS_PROD
ReactFabric-dev.js +0.4% +0.5% 496.97 KB 498.82 KB 109.22 KB 109.75 KB RN_FB_DEV
ReactFabric-prod.js 🔺+0.4% 🔺+0.2% 200.29 KB 201.09 KB 34.74 KB 34.83 KB RN_FB_PROD
ReactFabric-dev.js +0.4% +0.5% 497 KB 498.86 KB 109.23 KB 109.77 KB RN_OSS_DEV
ReactFabric-prod.js 🔺+0.4% 🔺+0.2% 200.32 KB 201.13 KB 34.76 KB 34.85 KB RN_OSS_PROD
ReactNativeRenderer-profiling.js +0.3% +0.2% 215.52 KB 216.27 KB 37.68 KB 37.75 KB RN_OSS_PROFILING
ReactFabric-profiling.js +0.4% +0.2% 207.43 KB 208.17 KB 36.23 KB 36.29 KB RN_OSS_PROFILING
ReactNativeRenderer-profiling.js +0.1% -0.1% 224.15 KB 224.43 KB 39.2 KB 39.18 KB RN_FB_PROFILING
ReactFabric-profiling.js +0.4% +0.2% 207.39 KB 208.13 KB 36.22 KB 36.28 KB RN_FB_PROFILING

scheduler

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
scheduler.development.js n/a n/a 0 B 19.17 KB 0 B 5.74 KB UMD_DEV
scheduler.production.min.js n/a n/a 0 B 3.16 KB 0 B 1.53 KB UMD_PROD
scheduler-tracing.development.js -0.9% -1.8% 10.25 KB 10.16 KB 2.35 KB 2.31 KB NODE_DEV
SchedulerTracing-dev.js -0.7% -1.2% 10.34 KB 10.27 KB 2.27 KB 2.25 KB FB_WWW_DEV

Generated by 🚫 dangerJS

@bvaughn bvaughn force-pushed the bvaughn:getDerivedStateFromCatch branch from d8700c1 to a18bc9f Sep 27, 2018

@bvaughn bvaughn changed the title Enable getDerivedStateFromCatch [WIP] Enable getDerivedStateFromError Sep 27, 2018

expect(renderer).toHaveRenderedChildren(
React.createElement(fallbackTagName, {prop: 'ErrorBoundary'}),
);
}

This comment has been minimized.

@bvaughn

bvaughn Sep 27, 2018

Author Contributor

This test was useful for me since my initial "fix" to sync mode broke concurrent mode. I'm not sure about this amount of abstraction though. On the one hand, it makes it very easy to spot what's different between these otherwise very similar tests. On the other hand, it may be harder to read.

workInProgress.child = null;
} else {
current.child = null;
}

This comment has been minimized.

@bvaughn

bvaughn Sep 27, 2018

Author Contributor

I'm not super confident about this fix ^

This comment has been minimized.

@acdlite

acdlite Sep 27, 2018

Member

Hmm, yeah I don't think this is right. I think I know how to fix it though. Let's pair on it tomorrow morning.

@@ -0,0 +1,2125 @@
/**

This comment has been minimized.

@bvaughn

bvaughn Sep 27, 2018

Author Contributor

This file was literally copied from ReactErrorBoundaries-test.internal.js so it doesn't really need to be reviewed. Normally I would have git mved it, but in this case– I wanted the reviewer to be able to easily spot the places the new render-phase error boundary behavior differed from the old behavior– so I modified the existing file.

@bvaughn bvaughn requested a review from acdlite Sep 27, 2018

@bvaughn bvaughn force-pushed the bvaughn:getDerivedStateFromCatch branch from a18bc9f to 3df17ba Sep 27, 2018

@bvaughn

This comment has been minimized.

Copy link
Contributor Author

bvaughn commented Sep 27, 2018

Rebased and added the DEV warning we talked about.

@acdlite
Copy link
Member

acdlite left a comment

Let's pair on the "force remount children" thing tomorrow

workInProgress.child = null;
} else {
current.child = null;
}

This comment has been minimized.

@acdlite

acdlite Sep 27, 2018

Member

Hmm, yeah I don't think this is right. I think I know how to fix it though. Let's pair on it tomorrow morning.

@bvaughn

This comment has been minimized.

Copy link
Contributor Author

bvaughn commented Sep 27, 2018

Hmm, yeah I don't think this is right. I think I know how to fix it though. Let's pair on it tomorrow morning.

Sounds great!

// If no state update is scheduled then the boundary will swallow the error.
const updateQueue = fiber.updateQueue;
warningWithoutStack(
updateQueue !== null && updateQueue.firstUpdate !== null,

This comment has been minimized.

@acdlite

acdlite Sep 27, 2018

Member

This check isn't sufficient because firstUpdate might be a low priority update. It needs to be sync. You can check fiber.expirationTime === Sync instead.

This comment has been minimized.

@bvaughn

bvaughn Sep 28, 2018

Author Contributor

Nice, thanks!

bvaughn added some commits Sep 28, 2018

Changed componentDidCatch no-state-update warning message to remove m…
…ention of throw

I think this is confusing because it implies that gDSFE can throw and cDC will still be called, when that is not the case (because cDC is a commit phase lifecycle- and if gDSFE rethrows, the boundary in question will never mount and the commit phase menthods it defines will not be called.

@bvaughn bvaughn force-pushed the bvaughn:getDerivedStateFromCatch branch from 333d4e7 to 54f637f Sep 28, 2018

@acdlite
Copy link
Member

acdlite left a comment

Yay

@bvaughn bvaughn merged commit 806eebd into facebook:master Sep 28, 2018

1 check passed

ci/circleci Your tests passed on CircleCI!
Details

@bvaughn bvaughn deleted the bvaughn:getDerivedStateFromCatch branch Sep 28, 2018

acdlite added a commit to plievone/react that referenced this pull request Oct 5, 2018

Enable getDerivedStateFromError (facebook#13746)
* Removed the enableGetDerivedStateFromCatch feature flag (aka permanently enabled the feature)
* Forked/copied ReactErrorBoundaries to ReactLegacyErrorBoundaries for testing componentDidCatch
* Updated error boundaries tests to apply to getDerivedStateFromCatch
* Renamed getDerivedStateFromCatch -> getDerivedStateFromError
* Warn if boundary with only componentDidCatch swallows error
* Fixed a subtle reconciliation bug with render phase error boundary

@gaearon gaearon referenced this pull request Oct 23, 2018

Merged

Add 16.6.0 changelog #13927

jetoneza added a commit to jetoneza/react that referenced this pull request Jan 23, 2019

Enable getDerivedStateFromError (facebook#13746)
* Removed the enableGetDerivedStateFromCatch feature flag (aka permanently enabled the feature)
* Forked/copied ReactErrorBoundaries to ReactLegacyErrorBoundaries for testing componentDidCatch
* Updated error boundaries tests to apply to getDerivedStateFromCatch
* Renamed getDerivedStateFromCatch -> getDerivedStateFromError
* Warn if boundary with only componentDidCatch swallows error
* Fixed a subtle reconciliation bug with render phase error boundary

iyegoroff added a commit to iyegoroff/react that referenced this pull request Mar 9, 2019

Enable getDerivedStateFromError (facebook#13746)
* Removed the enableGetDerivedStateFromCatch feature flag (aka permanently enabled the feature)
* Forked/copied ReactErrorBoundaries to ReactLegacyErrorBoundaries for testing componentDidCatch
* Updated error boundaries tests to apply to getDerivedStateFromCatch
* Renamed getDerivedStateFromCatch -> getDerivedStateFromError
* Warn if boundary with only componentDidCatch swallows error
* Fixed a subtle reconciliation bug with render phase error boundary
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.