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

Warn if MutableSource snapshot is a function #18933

Merged

Conversation

bvaughn
Copy link
Contributor

@bvaughn bvaughn commented May 15, 2020

Resolves #18823; potential alternative of #18921.

useMutableSource does not properly support snapshots that are functions. In part this is because of how it is implemented internally (the function gets mistaken for a state updater function). To "fix" this we could just wrap another function around the returned snapshot, but this pattern seems problematic to begin with- because the function that gets returned might itself close over mutable values, which would defeat the purpose of using the hook in the first place.

This PR proposes adding a new DEV warning if the snapshot returned is a function. It does not change the behavior (meaning that a function could still "work" in some cases- but at least the current behavior prevents passing around a closure that may later become stale unless you're really intentional about it e.g. () => () => {...}).

Open to discussion on whether we should lock it down further and treat this as an invariant.

@facebook-github-bot facebook-github-bot added CLA Signed React Core Team Opened by a member of the React Core Team labels May 15, 2020
if (typeof snapshot === 'function') {
console.warn(
'Mutable source should not return a functions as the snapshot value. ' +
'Functions may close over mutable values and cause tearing.',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This message probably isn't great. Happy to change it.

@bvaughn bvaughn force-pushed the useMutableSource-function-value-warning branch from 6f52afb to d45cd7d Compare May 15, 2020 20:17
@codesandbox-ci
Copy link

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 6f52afb:

Sandbox Source
inspiring-perlman-8oxl4 Configuration
happy-ishizaka-10ohr Issue #18823

@sizebot
Copy link

sizebot commented May 15, 2020

Details of bundled changes.

Comparing: 142d4f1...2c45e61

react-dom

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-dom-test-utils.development.js 0.0% 0.0% 75.66 KB 75.66 KB 20.23 KB 20.24 KB UMD_DEV
ReactDOMTesting-dev.js +0.1% 0.0% 935.24 KB 935.79 KB 208.97 KB 209.06 KB FB_WWW_DEV
react-dom-unstable-fizz.browser.production.min.js 0.0% 🔺+0.1% 1.2 KB 1.2 KB 705 B 706 B UMD_PROD
react-dom.development.js +0.1% 0.0% 950.45 KB 950.94 KB 207.86 KB 207.93 KB UMD_DEV
react-dom-server.browser.development.js 0.0% 0.0% 143.86 KB 143.86 KB 36.72 KB 36.72 KB UMD_DEV
ReactDOMForked-dev.js +0.1% 0.0% 1.01 MB 1.02 MB 232.77 KB 232.86 KB FB_WWW_DEV
react-dom.profiling.min.js 0.0% 0.0% 129.56 KB 129.56 KB 41.4 KB 41.4 KB UMD_PROFILING
react-dom.development.js +0.1% 0.0% 904.91 KB 905.37 KB 205.26 KB 205.33 KB NODE_DEV
react-dom-server.browser.development.js 0.0% 0.0% 136.47 KB 136.47 KB 36.26 KB 36.26 KB NODE_DEV
react-dom.production.min.js 0.0% 0.0% 125.64 KB 125.64 KB 39.23 KB 39.23 KB NODE_PROD
react-dom-server.browser.production.min.js 0.0% 0.0% 20.3 KB 20.3 KB 7.52 KB 7.52 KB NODE_PROD
react-dom.profiling.min.js 0.0% 0.0% 129.9 KB 129.9 KB 40.54 KB 40.55 KB NODE_PROFILING
ReactDOM-dev.js +0.1% 0.0% 1.01 MB 1.01 MB 230.59 KB 230.68 KB FB_WWW_DEV
ReactDOMServer-dev.js 0.0% 0.0% 143.94 KB 143.94 KB 36.57 KB 36.57 KB FB_WWW_DEV
react-dom-test-utils.development.js 0.0% 0.0% 70.47 KB 70.47 KB 19.74 KB 19.74 KB NODE_DEV
react-dom-test-utils.production.min.js 0.0% 0.0% 13.06 KB 13.06 KB 4.81 KB 4.81 KB NODE_PROD
react-dom-unstable-fizz.browser.production.min.js 0.0% 🔺+0.3% 1.02 KB 1.02 KB 616 B 618 B NODE_PROD
react-dom-server.node.development.js 0.0% 0.0% 137.74 KB 137.74 KB 36.51 KB 36.51 KB NODE_DEV

react-art

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-art.development.js +0.1% +0.1% 666.33 KB 666.82 KB 140.48 KB 140.55 KB UMD_DEV
react-art.production.min.js 0.0% 0.0% 111.15 KB 111.15 KB 33.68 KB 33.69 KB UMD_PROD
react-art.development.js +0.1% +0.1% 569.27 KB 569.74 KB 122.91 KB 122.99 KB NODE_DEV
react-art.production.min.js 0.0% 0.0% 76.1 KB 76.1 KB 22.85 KB 22.86 KB NODE_PROD
ReactART-dev.js +0.1% +0.1% 605.47 KB 606.01 KB 127.5 KB 127.59 KB FB_WWW_DEV
ReactART-prod.js 0.0% 0.0% 242.65 KB 242.65 KB 41.46 KB 41.46 KB FB_WWW_PROD

react-test-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-test-renderer-shallow.development.js 0.0% 0.0% 39.17 KB 39.17 KB 9.58 KB 9.58 KB UMD_DEV
react-test-renderer-shallow.production.min.js 0.0% -0.0% 12.74 KB 12.74 KB 3.97 KB 3.97 KB UMD_PROD
ReactTestRenderer-dev.js +0.1% +0.1% 579.07 KB 579.62 KB 122.66 KB 122.75 KB FB_WWW_DEV
react-test-renderer.development.js +0.1% +0.1% 578.55 KB 579.03 KB 120.71 KB 120.79 KB UMD_DEV
react-test-renderer.production.min.js 0.0% 0.0% 74.98 KB 74.98 KB 22.81 KB 22.81 KB UMD_PROD
react-test-renderer.development.js +0.1% +0.1% 551.62 KB 552.09 KB 119.3 KB 119.37 KB NODE_DEV
react-test-renderer.production.min.js 0.0% 0.0% 74.78 KB 74.78 KB 22.52 KB 22.52 KB NODE_PROD

react-reconciler

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-reconciler.development.js +0.1% 0.0% 626.76 KB 627.23 KB 133.04 KB 133.1 KB NODE_DEV
react-reconciler.production.min.js 0.0% 0.0% 85.93 KB 85.93 KB 25.68 KB 25.68 KB NODE_PROD
react-reconciler-reflection.production.min.js 0.0% 🔺+0.1% 2.93 KB 2.93 KB 1.21 KB 1.22 KB NODE_PROD

react-native-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactFabric-prod.js 0.0% 0.0% 264.45 KB 264.45 KB 45.53 KB 45.54 KB RN_OSS_PROD
ReactFabric-profiling.js 0.0% 0.0% 276.47 KB 276.47 KB 47.83 KB 47.83 KB RN_OSS_PROFILING
ReactNativeRenderer-profiling.js 0.0% 0.0% 284.52 KB 284.52 KB 49.35 KB 49.36 KB RN_OSS_PROFILING
ReactNativeRenderer-dev.js +0.1% +0.1% 667.74 KB 668.29 KB 143.36 KB 143.44 KB RN_FB_DEV
ReactNativeRenderer-prod.js 0.0% 0.0% 272.43 KB 272.43 KB 47.04 KB 47.04 KB RN_FB_PROD
ReactNativeRenderer-profiling.js 0.0% 0.0% 284.48 KB 284.48 KB 49.33 KB 49.33 KB RN_FB_PROFILING
ReactFabric-dev.js +0.1% +0.1% 644.43 KB 644.98 KB 138.2 KB 138.28 KB RN_OSS_DEV
ReactFabric-dev.js +0.1% +0.1% 648.92 KB 649.47 KB 138.87 KB 138.96 KB RN_FB_DEV
ReactNativeRenderer-dev.js +0.1% +0.1% 663.26 KB 663.81 KB 142.69 KB 142.77 KB RN_OSS_DEV

Size changes (experimental)

Generated by 🚫 dangerJS against 2c45e61

@sizebot
Copy link

sizebot commented May 15, 2020

Details of bundled changes.

Comparing: 142d4f1...2c45e61

react-native-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactFabric-dev.js +0.1% +0.1% 644.42 KB 644.97 KB 138.19 KB 138.28 KB RN_OSS_DEV
ReactNativeRenderer-dev.js +0.1% +0.1% 663.25 KB 663.8 KB 142.68 KB 142.76 KB RN_OSS_DEV
ReactNativeRenderer-profiling.js 0.0% 0.0% 284.51 KB 284.51 KB 49.35 KB 49.35 KB RN_OSS_PROFILING

react-dom

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-dom-test-utils.production.min.js 0.0% 0.0% 13.05 KB 13.05 KB 4.8 KB 4.8 KB NODE_PROD
react-dom-server.browser.development.js 0.0% 0.0% 136.36 KB 136.36 KB 34.88 KB 34.88 KB UMD_DEV
react-dom-unstable-fizz.node.production.min.js 0.0% 🔺+0.2% 1.16 KB 1.16 KB 659 B 660 B NODE_PROD
react-dom-server.browser.production.min.js 0.0% 0.0% 19.87 KB 19.87 KB 7.44 KB 7.44 KB UMD_PROD
ReactDOMForked-dev.js +0.1% 0.0% 1.04 MB 1.04 MB 238.58 KB 238.67 KB FB_WWW_DEV
react-dom.development.js +0.1% 0.0% 916.35 KB 916.83 KB 201.32 KB 201.4 KB UMD_DEV
react-dom.production.min.js 0.0% 0.0% 120.68 KB 120.68 KB 38.72 KB 38.73 KB UMD_PROD
ReactDOMTesting-dev.js +0.1% 0.0% 961.04 KB 961.59 KB 214.63 KB 214.72 KB FB_WWW_DEV
react-dom.development.js +0.1% 0.0% 872.26 KB 872.72 KB 198.78 KB 198.85 KB NODE_DEV
react-dom-server.node.development.js 0.0% 0.0% 130.61 KB 130.61 KB 34.69 KB 34.7 KB NODE_DEV
react-dom.production.min.js 0.0% 0.0% 120.8 KB 120.8 KB 37.79 KB 37.79 KB NODE_PROD
react-dom-test-utils.development.js 0.0% 0.0% 75.65 KB 75.65 KB 20.23 KB 20.23 KB UMD_DEV
react-dom.profiling.min.js 0.0% 0.0% 124.91 KB 124.91 KB 39.05 KB 39.05 KB NODE_PROFILING
react-dom-test-utils.production.min.js 0.0% 0.0% 13.17 KB 13.17 KB 4.89 KB 4.89 KB UMD_PROD
ReactDOM-dev.js +0.1% 0.0% 1.04 MB 1.04 MB 236.29 KB 236.38 KB FB_WWW_DEV
ReactDOM-prod.js 0.0% 0.0% 444.75 KB 444.75 KB 78.81 KB 78.81 KB FB_WWW_PROD
react-dom-server.browser.development.js 0.0% 0.0% 129.34 KB 129.34 KB 34.44 KB 34.44 KB NODE_DEV
react-dom-unstable-fizz.browser.production.min.js 0.0% 🔺+0.3% 1.19 KB 1.19 KB 697 B 699 B UMD_PROD
ReactDOMServer-dev.js 0.0% 0.0% 147.39 KB 147.39 KB 37.46 KB 37.46 KB FB_WWW_DEV
ReactDOMServer-prod.js 0.0% 0.0% 47.57 KB 47.57 KB 11.14 KB 11.14 KB FB_WWW_PROD
react-dom-unstable-fizz.browser.development.js 0.0% +0.1% 4.85 KB 4.85 KB 1.7 KB 1.7 KB NODE_DEV
react-dom-unstable-fizz.browser.production.min.js 0.0% 🔺+0.3% 1 KB 1 KB 609 B 611 B NODE_PROD

react-art

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactART-dev.js +0.1% +0.1% 615.48 KB 616.03 KB 129.54 KB 129.63 KB FB_WWW_DEV
ReactART-prod.js 0.0% 0.0% 249.68 KB 249.68 KB 42.71 KB 42.71 KB FB_WWW_PROD
react-art.development.js +0.1% +0.1% 641.71 KB 642.19 KB 135.49 KB 135.56 KB UMD_DEV
react-art.production.min.js 0.0% 0.0% 107.79 KB 107.79 KB 32.72 KB 32.72 KB UMD_PROD
react-art.development.js +0.1% +0.1% 545.66 KB 546.13 KB 117.92 KB 118 KB NODE_DEV
react-art.production.min.js 0.0% 0.0% 72.79 KB 72.79 KB 21.83 KB 21.83 KB NODE_PROD

react-test-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactTestRenderer-dev.js +0.1% +0.1% 579.05 KB 579.6 KB 122.66 KB 122.74 KB FB_WWW_DEV
react-test-renderer-shallow.development.js 0.0% 0.0% 39.16 KB 39.16 KB 9.57 KB 9.57 KB UMD_DEV
react-test-renderer-shallow.production.min.js 0.0% -0.0% 12.73 KB 12.73 KB 3.97 KB 3.96 KB UMD_PROD
react-test-renderer.development.js +0.1% +0.1% 578.52 KB 579.01 KB 120.7 KB 120.78 KB UMD_DEV
react-test-renderer.production.min.js 0.0% 0.0% 74.95 KB 74.95 KB 22.8 KB 22.8 KB UMD_PROD
react-test-renderer.development.js +0.1% +0.1% 551.6 KB 552.06 KB 119.29 KB 119.36 KB NODE_DEV
react-test-renderer.production.min.js 0.0% 0.0% 74.75 KB 74.75 KB 22.5 KB 22.5 KB NODE_PROD

react-reconciler

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-reconciler.development.js +0.1% +0.1% 600.77 KB 601.23 KB 127.57 KB 127.64 KB NODE_DEV
react-reconciler-reflection.development.js 0.0% 0.0% 17.71 KB 17.71 KB 5.24 KB 5.24 KB NODE_DEV
react-reconciler.production.min.js 0.0% 0.0% 82.2 KB 82.2 KB 24.58 KB 24.58 KB NODE_PROD
react-reconciler-reflection.production.min.js 0.0% 🔺+0.1% 2.92 KB 2.92 KB 1.21 KB 1.21 KB NODE_PROD

ReactDOM: size: 0.0%, gzip: 0.0%

Size changes (stable)

Generated by 🚫 dangerJS against 2c45e61

@codesandbox-ci
Copy link

codesandbox-ci bot commented May 15, 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 2c45e61:

Sandbox Source
weathered-haze-q2ufl Configuration
goofy-snowflake-th5sx Issue #18823

const snapshot = getSnapshot(source._source);
if (__DEV__) {
if (typeof snapshot === 'function') {
console.warn(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be console.error? Seems very error like if it might give wrong output and we might make it an invariant.

Brian Vaughn added 2 commits May 21, 2020 16:01
useMutableSource does not properly support snapshots that are functions. In part this is because of how it is implemented internally (the function gets mistaken for a state updater function). To fix this we could just wrap another function around the returned snapshot, but this pattern seems problematic to begin with- because the function that gets returned might itself close over mutable values, which would defeat the purpose of using the hook in the first place.

This PR proposes adding a new DEV warning if the snapshot returned is a function. It does not change the behavior (meaning that a function could still work in some cases- but at least the current behavior prevents passing around a closure that may later become stale unless you're really intentional about it e.g. () => () => {...}).
@bvaughn bvaughn force-pushed the useMutableSource-function-value-warning branch from d45cd7d to 2c45e61 Compare May 21, 2020 23:04
@bvaughn bvaughn merged commit 8f4dc3e into facebook:master May 21, 2020
@bvaughn bvaughn deleted the useMutableSource-function-value-warning branch May 21, 2020 23:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed React Core Team Opened by a member of the React Core Team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

useMutableSource: allow getSnapshot to return a function
4 participants