-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
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
[Modal] Refactor tests to remove internal accesses #16262
Conversation
@material-ui/lab: parsed: -0.42% 😍, gzip: -0.31% 😍 Details of bundle changes.Comparing: 93f5b33...44976a0
|
useEnhancedEffect(() => { | ||
if (onRendered && mountNode) { | ||
onRendered(); | ||
} | ||
}, [mountNode, onRendered]); | ||
|
||
React.useImperativeHandle(ref, () => mountNode || childRef.current, [mountNode]); |
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.
Change the order so ref
triggers before onRendered
.
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.
Wait refs should never trigger before layout effects. Those are two different phases. Do you have a test for that?
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.
useImperativeHandle
triggers at the same time than synchronous layout effects from what I can log (not layout effects!). I'm adding a test case.
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.
Huh, need to play around with this. Did not know that.
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 believe that reason is the following: you need to have access to the DOM element in the synchronous layout effects. If the ref triggers after, you don't have it.
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.
Did some experimenting and it is essentially facebook/react#7769 i.e. within a render block useImperativeHandle runs in the same phase as layout effects but any layout effect queued outside (e.g. in a parent) will run after useImperativeHandle of children.
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 onRendered
is actually an Anti-Pattern. We already have callback refs to handle when a host component is committed. What should happen is
- const portalRef = React.useRef();
- <Portal container={container} onRendered={() => doSomethingWith(portalRef.current)} ref={portalRef} />
+ <Portal container={container} ref={doSomethingWith} />
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.
Oh, interesting. I have never thought about it
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 we can re-evaluate dropping onRendered for callback refs in v5. For now this fix works.
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'm in favor of dropping the prop in v5. I will update the Modal implementation to stop using it in the next Modal pull request. Thanks for raising. I agree that it doesn't provide anything since the forwardRef effort was completed. 👌
@@ -1,10 +1,6 @@ | |||
import ownerDocument from '../utils/ownerDocument'; | |||
import ownerWindow from '../utils/ownerWindow'; | |||
|
|||
export function isBody(node) { |
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.
Dead code.
@@ -94,52 +94,43 @@ describe('<Modal />', () => { | |||
const wrapper = mount(modal); | |||
const onClose = spy(); | |||
wrapper.setProps({ onClose }); | |||
|
|||
const handler = wrapper.find('Modal').instance().handleBackdropClick; |
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.
Remove usages of .instance()
.
}), | ||
); | ||
|
||
export default function SimpleModal() { |
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.
Add a TypeScript demo 👌
import Dialog from 'packages/material-ui/src/Dialog'; | ||
import MenuItem from '@material-ui/core/MenuItem'; | ||
import Select from '@material-ui/core/Select'; | ||
import Dialog from '@material-ui/core/Dialog'; |
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 have removed all the usages of imports from packages/
. Better have fewer ways of doing the same thing!
}; | ||
|
||
export default withTheme(SwipeableDrawer); | ||
export default SwipeableDrawer; |
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.
Remove most of the usages of withTheme()
. It should help with perf, bundle size and debug noise.
@@ -69,10 +69,6 @@ Portal.propTypes = { | |||
onRendered: PropTypes.func, | |||
}; | |||
|
|||
Portal.defaultProps = { |
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.
Move some of the .defaultProps
to prop destructuring. I haven't migrated everything. I have left the complex objects and the one used in the custom prop-types.
useEnhancedEffect(() => { | ||
if (onRendered && mountNode) { | ||
onRendered(); | ||
} | ||
}, [mountNode, onRendered]); | ||
|
||
React.useImperativeHandle(ref, () => mountNode || childRef.current, [mountNode]); |
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.
Wait refs should never trigger before layout effects. Those are two different phases. Do you have a test for that?
4756d1f
to
89dde00
Compare
cf0664f
to
6ebe7f6
Compare
6ebe7f6
to
44976a0
Compare
Prepare #16254.
withTheme
touseTheme
..defaultProps
.ref
andonRendered
inversed call order.isEnabled
is not "stable".packages/material-ui/src/
imports with@material-ui/core/
.