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鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Tabs] Are not working with React.Suspense #14077
Comments
I believe this issue affects all layout methods used in |
This is due to how the scrollbar size is calculated when an element isn't visible it's offsetHeight and clientHeight are 0 which breaks the calculation as it's listening on window resizing |
@joshwooding I thought so. We might need another lifecycle hook to start these calculations as soon as this component is visible. |
Oh boy! React Suspense, what have you done! 馃槅 --- a/packages/material-ui/src/Tabs/ScrollbarSize.js
+++ b/packages/material-ui/src/Tabs/ScrollbarSize.js
@@ -2,6 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import EventListener from 'react-event-listener';
import debounce from 'debounce'; // < 1kb payload overhead when lodash/debounce is > 3kb.
+import Portal from '../Portal';
const styles = {
width: 90,
@@ -34,15 +35,15 @@ class ScrollbarSize extends React.Component {
}
}
- componentDidMount() {
- this.setMeasurements();
- this.props.onChange(this.scrollbarHeight);
- }
-
componentWillUnmount() {
this.handleResize.clear();
}
+ handleRendered = () => {
+ this.setMeasurements();
+ this.props.onChange(this.scrollbarHeight);
+ };
-
componentWillUnmount() {
this.handleResize.clear();
}
+ handleRendered = () => {
+ this.setMeasurements();
+ this.props.onChange(this.scrollbarHeight);
+ };
+
handleRef = ref => {
this.nodeRef = ref;
};
@@ -61,7 +62,9 @@ class ScrollbarSize extends React.Component {
return (
<React.Fragment>
<EventListener target="window" onResize={this.handleResize} />
- <div style={styles} ref={this.handleRef} />
+ <Portal onRendered={this.handleRendered}>
+ <div style={styles} ref={this.handleRef} />
+ </Portal>
</React.Fragment>
);
} Now, regarding the React lifecycles, I can't find anything we can leverage to trigger the tab indicator and scrollbar button display. I think that we should open an issue on React side. I doubt we are the only one with the problem. I think that React should provide an API to notify the components that the |
I have opened an issue on React side: facebook/react#14536. The Portal is really a dirty hack that only solves 1/3 of the issue. |
@joshwooding has found in #14181 that we can potentially use the |
I like this API but https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#Browser_compatibility |
Disclaimer: Don't use this in production. Fixed demo: https://codesandbox.io/s/6znx30q23w There are two heuristics for determining if a tree is suspended:
The first point will not work if no fallback is rendered i.e. maxDuration is not reached. The second point is all over the place since I tried to make it as memory safe as possible. It's also quite wasteful since I simply remount the Tabs once I think the tree is not supsended. |
I was looking at |
None of this (including react) is production ready so I think you're getting ahead of yourself if you're already thinking about performance. |
I do realise the code isn鈥檛 production ready. I was just adding my thoughts and just listing the potential downsides I had read about. 馃檪 |
Speaking about it: Do you have sources for this? Quick google search did not yield anything beyond specific problems on stackoverflow about bad performance of |
The entire point of using |
@eps1lon I can鈥檛 remember where I read it now. Maybe I misread something |
馃か You can also use CSS animation events to detect the visibility of a Dom node. Nevertheless I believe this issue needs to be fixed by react core. |
Hello, |
@Eldraed This is a common issue with Suspense in sync mode. React will still mount trees in an inconsistent state and just What you can do for now is remount the TextField if your placeholder unmounts with a If you can you could also put the suspense tree inside See facebook/react#14536 for more information. |
Thanks for the reply @eps1lon I tested Concurrent Mode before posting earlier, i didn't mention it. So, I'll rather look at your first option :) |
This is fixed with React 18 alpha. 17: https://codesandbox.io/s/material-ui-tabs-suspense-bug-forked-4n89l?file=/src/index.js
Not anymore! (Also, it's not a "mode" anymore either.) |
Closing since the underlying React issue has been closed as well. |
Expected Behavior 馃
Tabs should mount correctly when using
<React.Suspense>
Current Behavior 馃槸
Tabs do not render correctly when using
<React.Suspense>
.<TabIndicator />
is missingSteps to Reproduce 馃暪
Context 馃敠
I believe the issue here is that
componentDidMount
is called before the Component is visible.(
<React.Suspense>
renders theTabs
to a hiddendiv
).This causes all layout methods (
updateIndicatorState
,updateScrollButtonState
) to not work properly.Your Environment 馃寧
The text was updated successfully, but these errors were encountered: