[Tabs] Migrate to hooks#16427
Conversation
f321919 to
c1ced75
Compare
|
@material-ui/core: parsed: -1.06% 😍, gzip: -1.18% 😍 Details of bundle changes.Comparing: 7050cf5...bf006b8
|
f7efd43 to
78da4e8
Compare
After migrating the Slider and the Tabs tests to testing-library, I have a bit more hindsight on the value this testing library bring. I definitely agree that the tests are in better shape. However, the migration task was time-consuming. I'm not sure that the gain worth it. We might have been better off spending this time on a different problem. I would propose that we prioritize removing the shallow tests over migrating the existing tests to testing-library first. On a different note, I personally don't like the expect API. They are too many moving parts, take |
| "normalize-scroll-left": "^0.2.0", | ||
| "popper.js": "^1.14.1", | ||
| "prop-types": "^15.7.2", | ||
| "react-event-listener": "^0.6.6", |
There was a problem hiding this comment.
One less dependency :).
714e1b6 to
c867ede
Compare
c867ede to
b26a224
Compare
Nobody proposed migrating the existing ones. I merely introduced another API in case tests need to be refactored for other reasons (strict mode, shallow removal etc).
Agree 💯 jest already identified this problem and reduced chainability to I wouldn't mind using jest-expect over chai's expect. I didn't even think about using it since I thought it was coupled with the test runner. |
I believe that we (as a team) have introduced two ways of doing the same things (expect vs assert) and (enzyme vs testing-library). We should aim for simplicity, it's not OK to have two identical tools for the same job in the long run. However, we should also recognize that it's a necessary intermediate unideal state for improving the problems Material-UI tries to solve in the long term (providing the best possible React UI components). So I think that we should progressively remove the assert and enzyme usage from the codebase. Does it make sense?
I would have a preference for jest expect as it might be more useful for people using our tests as inspiration. But, it's not very important from my perspective. |
|
I will rebase the pull request to use the latest useEventCallback util and improve how the tests are written. |
b26a224 to
9e622ee
Compare
| marginBottom: null, | ||
| }); | ||
| const valueToIndex = React.useRef(); | ||
| valueToIndex.current = new Map(); |
There was a problem hiding this comment.
Is there a different with this vs const valueToIndex = React.useRef(new Map()) ?
There was a problem hiding this comment.
I believe that the useRef first argument is used for the initial value (https://codesandbox.io/s/laughing-chandrasekhar-grk1r).
How will we reset the Map instance between two renders?
There was a problem hiding this comment.
If it needs to reset between renders it makes sense to do it this way. Should we not calculate it when the children prop changes instead of every render?
I guess it might break ssr though I haven’t had a close look
There was a problem hiding this comment.
children prop (unless explicitly memoised) is typically written inline, so it's likely to be a new reference each time anyway 🙂
There was a problem hiding this comment.
So far, we are using the valueToIndex.current for:
- Warning when providing a wrong value
- Finding the selected tab item DOM node
There was a problem hiding this comment.
Finding the selected tab item DOM node
Should just attach a ref to it in v5. I think we allow custom tab components which means it would be breaking. If not then we can do it now.
There was a problem hiding this comment.
Actually thinking about it, for posterity & clarity maybe it's worth adding a comment to say why you're using a ref and not just a const valueToIndex = new Map() if you want it to reset every render?
There was a problem hiding this comment.
Should just attach a ref to it in v5.
@eps1lon +1 for looking into what we can improve on the ref side in v5. It's something we could have implemented this way in the first place. For some reason, we didn't. To dive into why it wasn't done this way.
maybe it's worth adding a comment to say why you're using a ref and not just a const valueToIndex = new Map() if you want it to reset every render?
@NMinhNguyen Seems that we don't need the ref in the first place 🙃. I have just tried without, it's all right. Doing some more tests and committing.
|
|
||
| const { tabsMeta, tabMeta } = this.getTabsMeta(value, theme.direction); | ||
| let left = 0; | ||
| window.addEventListener('resize', handleResize); |
There was a problem hiding this comment.
Probably doesn't matter because this is exactly equivalent to the old implementation but in the past we had issues in multi-window (window.open()) environments where window was referring to the parent window, and so the most bulletproof way was to do element.ownerDocument.defaultView to get the right window object (i.e. child not parent). I'm aware of the ownerWindow helper https://github.com/mui-org/material-ui/blob/89687f38cae750650555772ba4d821c9084d8dfc/packages/material-ui/src/utils/ownerWindow.js#L5 btw. It's just when I last looked at the implementation, I wasn't too sure why it falls back the way it does - parentView isn't a DOM property from what I can tell, nor is parentWindow from the original dom-helpers.
There was a problem hiding this comment.
@NMinhNguyen Interesting, we should probably use the ownerWindow and ownerDocument helpers for all our global event listeners to better support multi-window like use cases. We don't have a very strong support yet.
The parentView logic originally comes from react-bootstrap/dom-helpers@43fcc24#diff-991ea3fb4ae30d4ee9eda4d4f6ea9595. I would propose we remove it.
The fallback argument is also never used, we can use the same approach as in the ownerDocument helper.
There was a problem hiding this comment.
Yeah, except it says parentWindow in dom-helpers 😅. Regardless, I don't think either of those properties exist: parentView, parentWindow. At least I couldn't find them when googling.
There was a problem hiding this comment.
parentWindow seems to only be suported by IE and opera. Probably super old and just c&p (see over-polyfilling)
There was a problem hiding this comment.
Ah you’re right. We could change parentView -> parentWindow or remove it altogether I guess.
There was a problem hiding this comment.
dom-helpers supports older browsers (IE 8) than we do (IE 11). If we can remove parentView, it's even better.
There was a problem hiding this comment.
@NMinhNguyen Do you want to hit this with a pull request? 💥
There was a problem hiding this comment.
Yes, will do. I can wait until you merge this PR and then change window -> ownerWindow as well.
205c4b0 to
bf006b8
Compare
Related to #15231.