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

Properly warn on Symbol/Function in SSR, eliminate defaultValue and defaultChecked reserved words, fix some SSR mismatches #13394

Closed

Conversation

nhunzaker
Copy link
Contributor

Updates attribute table based on the latest Symbol stringification work.

| `value=(symbol)`| (changed, error, warning, ssr error)| `` |
| `value=(function)`| (changed, warning, ssr warning)| `"function f() {}"` |
| `value=(symbol)`| (initial, warning, ssr error, ssr mismatch)| `<empty string>` |
| `value=(function)`| (initial, warning, ssr mismatch)| `<empty string>` |
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do we have ssr error and ssr mismatch here but not in the other one? Can we fix SSR too?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I'm curious about that too. Writing a test for it now.

@@ -1237,10 +1244,6 @@ class ReactDOMServerRenderer {
}
}

if (__DEV__) {
validatePropertiesInDevelopment(tag, props);
}

This comment was marked as outdated.

@@ -831,7 +833,7 @@ class ReactDOMServerRenderer {
parentNamespace: string,
): string {
if (typeof child === 'string' || typeof child === 'number') {
const text = '' + child;
const text = toString(getToStringValue(child));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't like how both of these functions are essential to safely cast values to strings. I'd like to also export a function that just calls both of these.

Copy link
Contributor

Choose a reason for hiding this comment

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

We should probably get rid of this interim value completely. I’ve added it because we used this pattern in the input code but I feel like it caused a lot of confusion already 😕

Maybe we can keep the original value as mixed in the wrapper state?

I can work on that next week.

@pull-bot
Copy link

pull-bot commented Aug 14, 2018

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

Details of bundled changes.

Comparing: f6fb03e...da338d3

react-dom

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-dom.development.js -0.2% -0.3% 647.03 KB 645.84 KB 151.75 KB 151.35 KB UMD_DEV
react-dom.production.min.js 🔺+0.1% 🔺+0.2% 92.2 KB 92.3 KB 30.01 KB 30.08 KB UMD_PROD
react-dom.development.js -0.2% -0.3% 642.4 KB 641.19 KB 150.36 KB 149.96 KB NODE_DEV
react-dom.production.min.js 🔺+0.1% 🔺+0.1% 92.19 KB 92.24 KB 29.68 KB 29.7 KB NODE_PROD
react-dom-test-utils.development.js -0.1% -0.1% 44.66 KB 44.6 KB 12.19 KB 12.18 KB UMD_DEV
react-dom-test-utils.production.min.js -0.0% -0.2% 9.98 KB 9.98 KB 3.71 KB 3.71 KB UMD_PROD
react-dom-test-utils.development.js -0.1% -0.1% 44.38 KB 44.32 KB 12.13 KB 12.11 KB NODE_DEV
react-dom-test-utils.production.min.js -0.0% -0.0% 9.76 KB 9.76 KB 3.65 KB 3.65 KB NODE_PROD
react-dom-unstable-native-dependencies.development.js +26.4% +23.8% 60.27 KB 76.16 KB 15.79 KB 19.56 KB UMD_DEV
react-dom-unstable-native-dependencies.production.min.js 🔺+17.1% 🔺+18.3% 11 KB 12.88 KB 3.8 KB 4.5 KB UMD_PROD
react-dom-unstable-native-dependencies.development.js +26.5% +24.0% 59.94 KB 75.83 KB 15.67 KB 19.42 KB NODE_DEV
react-dom-unstable-native-dependencies.production.min.js 🔺+17.5% 🔺+18.4% 10.74 KB 12.62 KB 3.7 KB 4.38 KB NODE_PROD
ReactDOM-dev.js -0.2% -0.3% 664.73 KB 663.57 KB 152.76 KB 152.32 KB FB_WWW_DEV
ReactDOM-prod.js 🔺+0.5% 🔺+0.1% 286.06 KB 287.53 KB 53.13 KB 53.18 KB FB_WWW_PROD
ReactTestUtils-dev.js -0.1% -0.1% 41.47 KB 41.41 KB 11.18 KB 11.16 KB FB_WWW_DEV
ReactDOMUnstableNativeDependencies-dev.js +18.5% +14.4% 57.62 KB 68.28 KB 14.62 KB 16.73 KB FB_WWW_DEV
ReactDOMUnstableNativeDependencies-prod.js 🔺+24.6% 🔺+23.3% 26.27 KB 32.73 KB 5.3 KB 6.53 KB FB_WWW_PROD
react-dom.profiling.min.js -0.0% 0.0% 95.23 KB 95.19 KB 30.35 KB 30.36 KB NODE_PROFILING
ReactDOM-profiling.js +0.4% -0.1% 292.94 KB 294.08 KB 54.6 KB 54.53 KB FB_WWW_PROFILING

react-art

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-art.development.js -0.2% -0.3% 440.47 KB 439.51 KB 98.83 KB 98.53 KB UMD_DEV
react-art.production.min.js 🔺+0.1% 0.0% 84.62 KB 84.71 KB 25.98 KB 25.99 KB UMD_PROD
react-art.development.js -0.3% -0.4% 372.24 KB 371.26 KB 81.7 KB 81.41 KB NODE_DEV
react-art.production.min.js 🔺+0.2% 🔺+0.2% 49.58 KB 49.67 KB 15.24 KB 15.27 KB NODE_PROD
ReactART-dev.js -0.2% -0.4% 377.19 KB 376.26 KB 80.54 KB 80.17 KB FB_WWW_DEV
ReactART-prod.js 🔺+0.2% 🔺+0.2% 159.88 KB 160.23 KB 27.11 KB 27.16 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.3% -0.4% 384.3 KB 383.26 KB 84.3 KB 83.99 KB UMD_DEV
react-test-renderer.production.min.js 🔺+0.2% -0.1% 50.78 KB 50.87 KB 15.54 KB 15.53 KB UMD_PROD
react-test-renderer.development.js -0.3% -0.4% 379.91 KB 378.85 KB 83.17 KB 82.85 KB NODE_DEV
react-test-renderer.production.min.js 🔺+0.2% 0.0% 50.49 KB 50.58 KB 15.38 KB 15.38 KB NODE_PROD
react-test-renderer-shallow.development.js 0.0% +0.2% 24.29 KB 24.29 KB 6.61 KB 6.62 KB UMD_DEV
react-test-renderer-shallow.production.min.js 🔺+0.1% -0.2% 7.16 KB 7.17 KB 2.35 KB 2.34 KB UMD_PROD
react-test-renderer-shallow.development.js 0.0% +0.3% 19.48 KB 19.48 KB 5.41 KB 5.42 KB NODE_DEV
ReactTestRenderer-dev.js -0.3% -0.5% 384.98 KB 383.97 KB 82.26 KB 81.88 KB FB_WWW_DEV
ReactShallowRenderer-dev.js 0.0% +0.3% 17.8 KB 17.8 KB 4.67 KB 4.69 KB FB_WWW_DEV

react-noop-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-noop-renderer.development.js -1.3% -1.0% 23.91 KB 23.6 KB 5.4 KB 5.34 KB NODE_DEV
react-noop-renderer.production.min.js -0.6% -0.6% 8.91 KB 8.86 KB 3.1 KB 3.08 KB NODE_PROD
react-noop-renderer-persistent.development.js -1.3% -1.0% 24.02 KB 23.72 KB 5.41 KB 5.36 KB NODE_DEV
react-noop-renderer-persistent.production.min.js -0.6% -0.6% 8.93 KB 8.88 KB 3.1 KB 3.08 KB NODE_PROD

react-reconciler

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-reconciler.development.js -0.3% -0.4% 368.14 KB 367.16 KB 79.83 KB 79.52 KB NODE_DEV
react-reconciler.production.min.js -0.1% -0.1% 49.28 KB 49.24 KB 14.79 KB 14.78 KB NODE_PROD
react-reconciler-persistent.development.js -0.3% -0.4% 366.68 KB 365.7 KB 79.26 KB 78.95 KB NODE_DEV
react-reconciler-persistent.production.min.js -0.1% -0.1% 49.29 KB 49.25 KB 14.79 KB 14.78 KB NODE_PROD

react-native-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactNativeRenderer-dev.js -0.2% -0.3% 499.47 KB 498.55 KB 110.72 KB 110.4 KB RN_FB_DEV
ReactNativeRenderer-prod.js 🔺+0.1% 🔺+0.1% 214.83 KB 215.13 KB 37.46 KB 37.48 KB RN_FB_PROD
ReactNativeRenderer-dev.js -0.2% -0.3% 499.2 KB 498.29 KB 110.65 KB 110.33 KB RN_OSS_DEV
ReactNativeRenderer-prod.js 🔺+0.1% 🔺+0.1% 204.65 KB 204.95 KB 35.81 KB 35.84 KB RN_OSS_PROD
ReactFabric-dev.js -0.2% -0.3% 489.73 KB 488.74 KB 108.33 KB 107.98 KB RN_FB_DEV
ReactFabric-prod.js 🔺+0.1% -0.0% 197.07 KB 197.33 KB 34.35 KB 34.34 KB RN_FB_PROD
ReactFabric-dev.js -0.2% -0.3% 489.77 KB 488.77 KB 108.34 KB 108 KB RN_OSS_DEV
ReactFabric-prod.js 🔺+0.1% -0.0% 197.1 KB 197.37 KB 34.36 KB 34.35 KB RN_OSS_PROD
ReactNativeRenderer-profiling.js -0.1% -0.4% 212.38 KB 212.25 KB 37.34 KB 37.19 KB RN_OSS_PROFILING
ReactFabric-profiling.js -0.2% -0.6% 204.28 KB 203.89 KB 35.9 KB 35.69 KB RN_OSS_PROFILING
ReactNativeRenderer-profiling.js -0.1% -0.4% 220.85 KB 220.73 KB 38.85 KB 38.68 KB RN_FB_PROFILING
ReactFabric-profiling.js -0.2% -0.6% 204.24 KB 203.85 KB 35.88 KB 35.68 KB RN_FB_PROFILING

schedule

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
schedule.development.js n/a n/a 0 B 19.17 KB 0 B 5.74 KB UMD_DEV
schedule.production.min.js n/a n/a 0 B 3.16 KB 0 B 1.53 KB UMD_PROD

Generated by 🚫 dangerJS

@nhunzaker
Copy link
Contributor Author

@gaearon making headway, but it looks like SSR needs a few more changes to make the warning consistent. I need to shift gears, but I'll circle back.

@gaearon
Copy link
Collaborator

gaearon commented Aug 14, 2018

I'm wary of how much mental abstraction overhead it feels like ToString stuff is adding. Maybe we can still come up with better naming. Or maybe just test coverage is enough and we can undo the abstraction.

@@ -11855,21 +11855,21 @@
| `value=(empty string)`| (initial)| `<empty string>` |
| `value=(array with string)`| (changed)| `"string"` |
| `value=(empty array)`| (initial)| `<empty string>` |
| `value=(object)`| (changed)| `"result of toString()"` |
| `value=(object)`| (changed, ssr error, ssr mismatch)| `"result of toString()"` |
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 should line up, adding unit test.

@nhunzaker
Copy link
Contributor Author

Working through this, but the trend is that we don't need to rely so much on the ToString stuff. We just need to determine if a value is stringifiable on certain cases for textarea warnings.

}

props = Object.assign({}, props, {
value: undefined,
children: '' + initialValue,
children: initialValue,
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 appears to produce the effect I want, but it's gross. Now that it works as I think it should, I'll work on making the code better.

| `value=(symbol)`| (changed, error, warning, ssr error)| `` |
| `value=(function)`| (changed, warning, ssr warning)| `"function f() {}"` |
| `value=(symbol)`| (initial, warning)| `<empty string>` |
| `value=(function)`| (initial, warning)| `<empty string>` |
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure if I'm interpreting this correctly. I'm working off of:

image

In any case, this appears to fix a behavior where functions were stringified into textareas instead of converting into empty strings. There is no longer a mismatch.

Still I can't figure out why ssr warning went away, even though I can confirm the warning in unit tests.

| `value=(symbol)`| (changed, error, warning, ssr mismatch)| `` |
| `value=(function)`| (changed, warning, ssr mismatch)| `"function f() {}"` |
| `value=(symbol)`| (initial, warning)| `<empty string>` |
| `value=(function)`| (initial, warning)| `<empty string>` |
| `value=(null)`| (initial)| `<empty string>` |
| `value=(undefined)`| (initial)| `<empty string>` |
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Took care of quite a few mismatches :)

@nhunzaker
Copy link
Contributor Author

nhunzaker commented Aug 15, 2018

Okay! Validating the properties before processing them took care of all of the warnings, and not stringifying values appears to fix a lot of SSR mismatch issues too.

I hope I've interpreted this correctly. I'd like to add some documentation to the attribute table to help clear that up (follow up PR)

| `value=(float)`| (changed)| `"99.99"` |
| `value=(true)`| (changed)| `"true"` |
| `value=(false)`| (changed)| `"false"` |
| `value=(string 'true')`| (changed)| `"true"` |
| `value=(string 'false')`| (changed)| `"false"` |
| `value=(string 'on')`| (changed)| `"on"` |
| `value=(string 'off')`| (changed)| `"off"` |
| `value=(symbol)`| (changed, error, warning, ssr error)| `` |
| `value=(function)`| (changed, warning, ssr warning)| `"function f() {}"` |
| `value=(null)`| (initial, warning, ssr warning)| `<empty string>` |
Copy link
Contributor Author

@nhunzaker nhunzaker Aug 15, 2018

Choose a reason for hiding this comment

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

Trying to figure this one out. Unit tests suggest that a warning is firing using SSR. Does this mean that the attribute table didn't see a SSR warning?

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's good when you don't have ssr warning. Just warning means everything is consistent between client and server.

ssr warning confusingly means "client and server match in behavior except warnings". So it's bad to have it.

@nhunzaker nhunzaker force-pushed the update-attribute-table-with-symbols branch from 0f6766e to c2bcd60 Compare August 15, 2018 22:23
@nhunzaker
Copy link
Contributor Author

Hmm... Why is CI running out of memory...

@@ -222,6 +222,41 @@ describe('ReactDOMServerIntegration', () => {
expect(e.value).toBe('foo');
},
);

itRenders('a textarea with Symbol value with a warning', async render => {
Copy link
Contributor

Choose a reason for hiding this comment

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

What about passing a function as a value? Should we test that here as well?

Also, defaultValue?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Definitely. Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great catch. Working through some changes now that actually eliminate all of our todos about warning on defaultValue.

@nhunzaker nhunzaker force-pushed the update-attribute-table-with-symbols branch from c2bcd60 to e168b66 Compare August 16, 2018 19:19
@nhunzaker
Copy link
Contributor Author

Okay, this ended up being a bigger change than I realized, but I'm to the point where defaultValue and defaultChecked no longer need to be reserved.

Also it looks like a lot of boolean attributes weren't sending warnings before.

].forEach(function(name) {
properties[name] = new PropertyInfoRecord(
name,
BOOLEANISH_STRING,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yikes, this should be OVERLOADED_BOOLEAN

Copy link
Contributor Author

@nhunzaker nhunzaker left a comment

Choose a reason for hiding this comment

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

I think this is to the point where it needs to be reviewed. Build failure is because CI runs out of memory:

Security context: 0x877bda25879 <JSObject>
    1: requireModule [/home/circleci/project/node_modules/jest-runtime/build/index.js:~309] [pc=0x2390cf094548](this=0x45e22389941 <Runtime map = 0x1b6113890011>,from=0x1037f9641259 <String[56]: /home/circleci/project/packages/events/EventPluginHub.js>,moduleName=0xea6753597c9 <String[25]: shared/reactProdInvariant>,options=0x29972df822d1 <undefined>)
    2: arguments adaptor frame: 2->3
    3: r...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory

The server integration tests are really heavy. I wonder if all of the extra tests in this suite are to blame.

trapBubbledEvent(TOP_INVALID, domElement);
// For controlled components we always need to ensure we're listening
// to onChange. Even if there is no listener.
ensureListeningTo(rootContainerElement, 'onChange');
break;
case 'textarea':
ReactDOMFiberTextarea.initWrapperState(domElement, rawProps);
props = ReactDOMFiberTextarea.getHostProps(domElement, rawProps);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

With this addition, I think this set of operations is exactly the same for hydration and client-rendering. Also I think they need to be the same for SSR to align warning behavior. Maybe these should be in a shared function.

@nhunzaker
Copy link
Contributor Author

Looks like the boolean warnings weren't a result of this PR (thankfully; this was bugging me). I sent out a PR for that here:
#13421

We don't have to merge it, but I'd appreciate it so that it's easier to see the effects on the attribute table of this PR.

@nhunzaker nhunzaker force-pushed the update-attribute-table-with-symbols branch from 6a8a9af to 9c62214 Compare August 16, 2018 20:40
@gaearon
Copy link
Collaborator

gaearon commented Aug 16, 2018

Time to rename the PR? :-)

@nhunzaker nhunzaker changed the title Update attribute-table Properly warn on Symbol/Function, eliminate defaultValue and defaultChecked reserved words, fix some SSR mismatches Aug 16, 2018
@nhunzaker
Copy link
Contributor Author

Wasn't quite sure how to summarize it, so I just wrote everything

@nhunzaker nhunzaker changed the title Properly warn on Symbol/Function, eliminate defaultValue and defaultChecked reserved words, fix some SSR mismatches Properly warn on Symbol/Function in SSR, eliminate defaultValue and defaultChecked reserved words, fix some SSR mismatches Aug 16, 2018
@gaearon
Copy link
Collaborator

gaearon commented Aug 16, 2018

Is it ready for review?

@nhunzaker
Copy link
Contributor Author

Assuming this approach is acceptable, I think this is good to merge.

nhunzaker added a commit to nhunzaker/react that referenced this pull request Sep 8, 2018
In facebook#13394, I encountered an
issue where the ReactDOMServerIntegrationForm test suite consumed
sufficient memory to crash CircleCI. Breaking up this test suite by
form element type resolved the issue.

This commit performs that change separate from the Symbol/Function
stringification changes in facebook#13394.
nhunzaker added a commit to nhunzaker/react that referenced this pull request Sep 8, 2018
In facebook#13394, I encountered an
issue where the ReactDOMServerIntegrationForm test suite consumed
sufficient memory to crash CircleCI. Breaking up this test suite by
form element type resolved the issue.

This commit performs that change separate from the Symbol/Function
stringification changes in facebook#13394.
nhunzaker added a commit that referenced this pull request Sep 8, 2018
In #13394, I encountered an
issue where the ReactDOMServerIntegrationForm test suite consumed
sufficient memory to crash CircleCI. Breaking up this test suite by
form element type resolved the issue.

This commit performs that change separate from the Symbol/Function
stringification changes in #13394.
@nhunzaker nhunzaker force-pushed the update-attribute-table-with-symbols branch 5 times, most recently from 7342c79 to 9a33f99 Compare September 8, 2018 18:44

let options;
beforeEach(function() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Didn't catch this in the rebase, patching up.

@nhunzaker
Copy link
Contributor Author

Everything is up to date with master (including the ReactDOMServerIntegrationForm-test split). I've also verified that there is no change to the attribute table from updates on master.

* Add to-string protection to SSR
* Add validation step to inputs
* Only validate textarea value prop
* Properly handle true/false and NaN
* Simplify validation by doing it ahead of time
* Tweak toStringValue comment
* defaultValue and defaultChecked are no longer reserved words
* Use correct type for defaultValue and defaultChecked
* Add test coverage and fixes for mixed type selection on options
* Improve comment about backwards compatibility with defaultValue
* Align defaultValue and defaultChecked with value and checked
@nhunzaker nhunzaker force-pushed the update-attribute-table-with-symbols branch from 30dc406 to da338d3 Compare September 11, 2018 00:04
Simek pushed a commit to Simek/react that referenced this pull request Oct 25, 2018
In facebook#13394, I encountered an
issue where the ReactDOMServerIntegrationForm test suite consumed
sufficient memory to crash CircleCI. Breaking up this test suite by
form element type resolved the issue.

This commit performs that change separate from the Symbol/Function
stringification changes in facebook#13394.
jetoneza pushed a commit to jetoneza/react that referenced this pull request Jan 23, 2019
In facebook#13394, I encountered an
issue where the ReactDOMServerIntegrationForm test suite consumed
sufficient memory to crash CircleCI. Breaking up this test suite by
form element type resolved the issue.

This commit performs that change separate from the Symbol/Function
stringification changes in facebook#13394.
@stale
Copy link

stale bot commented Jan 10, 2020

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution.

@stale stale bot added the Resolution: Stale Automatically closed due to inactivity label Jan 10, 2020
@stale
Copy link

stale bot commented Jan 17, 2020

Closing this pull request after a prolonged period of inactivity. If this issue is still present in the latest release, please ask for this pull request to be reopened. Thank you!

@stale stale bot closed this Jan 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed Resolution: Stale Automatically closed due to inactivity
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants