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

Fix state leaking when a function component throws on server render #19212

Merged
merged 6 commits into from Jul 8, 2020

Conversation

@pmaccart
Copy link
Contributor

@pmaccart pmaccart commented Jun 30, 2020

Summary

Reset the internal hooks state when preparing a component for hooks usage, rather than after a component finishes rendering. This fixes #19211, where the internal hooks state is not cleared if a function component throws an error while rendering.

Test Plan

@facebook-github-bot
Copy link

@facebook-github-bot facebook-github-bot commented Jun 30, 2020

Hi @pmaccart!

Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file.

In order for us to review and merge your code, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

If you have received this in error or have any questions, please contact us at cla@fb.com. Thanks!

@sizebot
Copy link

@sizebot sizebot commented Jun 30, 2020

No significant bundle size changes to report.

Size changes (stable)

Generated by 🚫 dangerJS against 21fdac0

@sizebot
Copy link

@sizebot sizebot commented Jun 30, 2020

No significant bundle size changes to report.

Size changes (experimental)

Generated by 🚫 dangerJS against 21fdac0

@gaearon
Copy link
Member

@gaearon gaearon commented Jun 30, 2020

Can you add a test that would have been failing before? That would make it easier to check the changes.

@gaearon
Copy link
Member

@gaearon gaearon commented Jun 30, 2020

Can we instead add resetHooksAfterThrow, mirroring what we do in ReactFiberHooks?

@FiberesimaJoseph

This comment was marked as off-topic.

@codesandbox
Copy link

@codesandbox codesandbox bot commented Jul 7, 2020

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 21fdac0:

Sandbox Source
React Configuration
@pmaccart pmaccart force-pushed the pmaccart:reset-hooks-state-before-render branch 6 times, most recently from 6dad98b to 46556a4 Jul 7, 2020
@pmaccart pmaccart force-pushed the pmaccart:reset-hooks-state-before-render branch from 46556a4 to 398116c Jul 7, 2020
@pmaccart
Copy link
Contributor Author

@pmaccart pmaccart commented Jul 7, 2020

@gaearon Thanks for the feedback, and sorry for the slow response.

I made a couple updates to the PR:

  1. Added a unit test that fails prior to the fix (64f35a1)
  2. Added a commit that implements a similar approach to what is taken in ReactFiberHooks -- eager to get your feedback on whether this approach is preferable, or whether we want to stick with resetting the state in the prepareToUseHooks function. Happy to go either way on this.
if (__DEV__) {
isInHookUserCodeInDev = false;
}

// These were reset above
// These were reset via the resetHooksState() call

This comment has been minimized.

@gaearon

gaearon Jul 7, 2020
Member

Let's just remove this comment?

This comment has been minimized.

@pmaccart

pmaccart Jul 7, 2020
Author Contributor

Done.

numberOfReRenders = 0;
renderPhaseUpdates = null;
workInProgressHook = null;
resetHooksState();
if (__DEV__) {

This comment has been minimized.

@gaearon

gaearon Jul 7, 2020
Member

Move this DEV-only block to reset too?

This comment has been minimized.

@pmaccart

pmaccart Jul 7, 2020
Author Contributor

Done.

@gaearon gaearon changed the title Reset internal hooks state before rendering Fix state leaking when a function component throws on server render Jul 8, 2020
@@ -202,24 +202,21 @@ export function finishHooks(

children = Component(props, refOrContext);
}
currentlyRenderingComponent = null;

This comment has been minimized.

@gaearon

gaearon Jul 8, 2020
Member

Did we lose currentlyRenderingComponent?

This comment has been minimized.

@pmaccart

pmaccart Jul 8, 2020
Author Contributor

Oops, yes -- added that in as well.

@gaearon
gaearon approved these changes Jul 8, 2020
@gaearon gaearon merged commit b85b476 into facebook:master Jul 8, 2020
32 checks passed
32 checks passed
Facebook CLA Check Contributor License Agreement is valid!
Details
ci/circleci: RELEASE_CHANNEL_stable_yarn_build Your tests passed on CircleCI!
Details
ci/circleci: RELEASE_CHANNEL_stable_yarn_lint_build Your tests passed on CircleCI!
Details
ci/circleci: RELEASE_CHANNEL_stable_yarn_test Your tests passed on CircleCI!
Details
ci/circleci: RELEASE_CHANNEL_stable_yarn_test_build Your tests passed on CircleCI!
Details
ci/circleci: RELEASE_CHANNEL_stable_yarn_test_build_prod Your tests passed on CircleCI!
Details
ci/circleci: RELEASE_CHANNEL_stable_yarn_test_dom_fixtures Your tests passed on CircleCI!
Details
ci/circleci: RELEASE_CHANNEL_stable_yarn_test_persistent Your tests passed on CircleCI!
Details
ci/circleci: RELEASE_CHANNEL_stable_yarn_test_prod Your tests passed on CircleCI!
Details
ci/circleci: RELEASE_CHANNEL_stable_yarn_test_prod_www Your tests passed on CircleCI!
Details
ci/circleci: RELEASE_CHANNEL_stable_yarn_test_prod_www_variant Your tests passed on CircleCI!
Details
ci/circleci: RELEASE_CHANNEL_stable_yarn_test_www Your tests passed on CircleCI!
Details
ci/circleci: RELEASE_CHANNEL_stable_yarn_test_www_variant Your tests passed on CircleCI!
Details
ci/circleci: process_artifacts Your tests passed on CircleCI!
Details
ci/circleci: process_artifacts_experimental Your tests passed on CircleCI!
Details
ci/circleci: setup Your tests passed on CircleCI!
Details
ci/circleci: sizebot_experimental Your tests passed on CircleCI!
Details
ci/circleci: sizebot_stable Your tests passed on CircleCI!
Details
ci/circleci: yarn_build Your tests passed on CircleCI!
Details
ci/circleci: yarn_flow Your tests passed on CircleCI!
Details
ci/circleci: yarn_lint Your tests passed on CircleCI!
Details
ci/circleci: yarn_lint_build Your tests passed on CircleCI!
Details
ci/circleci: yarn_test Your tests passed on CircleCI!
Details
ci/circleci: yarn_test_build Your tests passed on CircleCI!
Details
ci/circleci: yarn_test_build_devtools Your tests passed on CircleCI!
Details
ci/circleci: yarn_test_build_prod Your tests passed on CircleCI!
Details
ci/circleci: yarn_test_prod Your tests passed on CircleCI!
Details
ci/circleci: yarn_test_prod_www Your tests passed on CircleCI!
Details
ci/circleci: yarn_test_prod_www_variant Your tests passed on CircleCI!
Details
ci/circleci: yarn_test_www Your tests passed on CircleCI!
Details
ci/circleci: yarn_test_www_variant Your tests passed on CircleCI!
Details
ci/codesandbox Building packages succeeded.
Details
@gaearon
Copy link
Member

@gaearon gaearon commented Jul 8, 2020

Looks good. Thx

trueadm added a commit to trueadm/react that referenced this pull request Jul 8, 2020
…acebook#19212)

* add unit test asserting internal hooks state is reset

* Reset internal hooks state before rendering

* reset hooks state on error

* Use expect...toThrow instead of try/catch in test

* reset dev-only hooks state inside resetHooksState

* reset currentlyRenderingComponent to null
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

5 participants
You can’t perform that action at this time.