-
Notifications
You must be signed in to change notification settings - Fork 58
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
CPLAT-7979: Add SafeRenderManager #390
Conversation
Security InsightsNo security relevant content was detected by automated scans. Action Items
Questions or Comments? Reach out on Slack: #support-infosec. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good! Just a couple of minor things.
lib/src/util/safe_render_manager/safe_render_manager_helper.dart
Outdated
Show resolved
Hide resolved
lib/src/util/safe_render_manager/safe_render_manager_helper.dart
Outdated
Show resolved
Hide resolved
5d67fba
to
48ae01c
Compare
1b604da
to
db9478d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work @greglittlefield-wf !!! All the shared tests are particularly detailed, which should provide consumers with great confidence to integrate this into their libs.
Aside from a few suggestions / questions... The copyright stuff needs to be added to the top of all the new files:
// Copyright 2019 Workiva Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Don't do this in a finally since onMaybeUnmounted can get called async. | ||
callOnMaybeUnmounted(true); | ||
rethrow; | ||
} | ||
} else { | ||
try { | ||
_unmountContent(); | ||
} finally { | ||
callOnMaybeUnmounted(true); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the comment on line 162 apply to line 170?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, since there isn't a onMaybeUnmounted
callback being used here.
|
||
void tryUnmountContent({void onMaybeUnmounted(bool isUnmounted)}) { | ||
setState(newState()..content = null, () { | ||
onMaybeUnmounted?.call(state.content == null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity - is it possible for state.content
to be non-null within a callback of a call to setState
that sets state.content
to null
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes; this can happen if this setState is batched with another setState that sets it to something else.
expect(renderManager.mountNode.parent, document.body); | ||
|
||
renderManager.tryUnmount(); | ||
expect(renderManager.mountNode.parent, isNull); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realize this is probably kosher - but when I first read this - I thought... it... null'd document.body
??!!?!!?
Not saying you have to change it, but something like this would test the same thing:
expect(document.body.contains(renderManager.mountNode), isFalse);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually had this exact thing at first, but then changed it to what I have now so that the failure messages would be more helpful.
Expected: null
Actual: BodyElement
vs
Expected: false
Actual: true
renderManager.render(Dom.div()()); | ||
expect(renderManager.mountNode.parent, isNull); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If mountNode
is not specified, and autoAttachMountNode
is false... isn't that an invalid configuration? What would it render into?
I realize this test is not really testing that - I'm just saying that the conditions of this test made me think this probably shouldn't be supported.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it's a valid configuration. The manager defaults to a new, empty div if one isn't specified, and the consumer would be responsible for attaching/detaching it from the DOM.
} | ||
|
||
if (isThrowingTest) { | ||
expect(mountNode.text, isEmpty, reason: 'test setup check: React should have unmounted throwing component tree'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will we just remove this logic when we port this change into 2.x
stable?
There was a problem hiding this 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 good to keep in as a sanity check
} | ||
)('setup render')); | ||
|
||
// Use a real click since simulated clicks don't trigger this async behavior |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💯
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to alpha release... feedback will be addressed in a follow-up PR.
@Workiva/release-management-pp
Motivation
There were some cases where top-level
react_dom.render
/.unmountComponentAtNode
calls were being done from within the event handlers and lifecycle methods of React components, which encountered timing-related issues in React 16.Changes
Release Notes
ReactElement
into a given node, with support for safely rendering, updating, and unmounting content.Review
See CONTRIBUTING.md for more details on review types (+1 / QA +1 / +10) and code review process.
Please review:
QA Checklist
Merge Checklist
While we perform many automated checks before auto-merging, some manual checks are needed: