-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Add hooks and HOCs to lib/viewport
#31081
Conversation
|
||
// Disable console warnings for this file. | ||
// eslint-disable-next-line no-console | ||
console.warn = jest.fn(); |
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.
that's a global change though isn't 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.
Doesn't every file run separately in Jest?
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.
just saying that this relies on jest isolating globals on test runs across each test file. is that a safe assumption?
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.
It does seem potentially dangerous, I agree. I'll find a better way of doing this.
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.
Done, using spies now.
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.
thanks!
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.
just saying that this relies on jest isolating globals on test runs across each test file. is that a safe assumption?
I agree with doing the mocks as if the globals were not isolated, but it's safe to assume that they are. The global is sandboxed, provided by the jest-environment
as configured globally or per-file, and recreated for each file.
Each Jest file can specify a pragma at the beginning:
/**
* @jest-environment jsdom
*/
A rather unavoidable conclusion of this is that the global is different for each file, either Node-ish or browser-ish.
e1d2cfe
to
eaaca21
Compare
All comments addressed, and several improvements made. Ready for another look. |
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.
LGTM, but I'd love @jsnajdr to look it over too.
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 not enthusiastic about the new addWithinBreakpointListener
API. There are two common patterns for adding and removing listeners:
addListener and removeListener that relies on listener's identity
Common in DOM APIs and in Node.js, standardized as EventTarget
:
const listener = () => { ... };
el.addEventListener( 'scroll', listener );
el.removeEventListener( 'scroll', listener );
To remove a listener, exactly the same listener object must be passed to the remove function. Both functions return void.
subscribe function that returns an unsubscribe function
Used in Redux (store.subscribe
), in RxJS and in React.useEffect
:
const unsubscribe = subscribe( listener );
// forget the listener, remember the unsubscribe function
unsubscribe();
Can we choose one of the patterns and stick to it? addWithinBreakpointListener
is now a confusing mixture of both.
You're right, it did get pretty confusing. I switched to the latter method, which neatly allows us to reduce the API surface and keep it more consistent 👍 |
Thank you for the excellent review as usual, @jsnajdr! 👍 All comments addressed. |
New comments addressed as well. Thanks again, @jsnajdr ! |
849a5ab
to
128f1f8
Compare
It wasn't removing listeners properly, causing components to be updated after unmounting.
Also refactors some components to make use of the new helpers.
This allows the same listener to be used more than once. Also reimplements `withBreakpoint` using `useBreakpoint`.
This is much cleaner than maintaining a bunch of unsubscribe methods and storing a pointer too.
128f1f8
to
b2ffccb
Compare
Changing to a different breakpoint should now produce an immediate correct result, without needing to wait for an effect to fire. There should be no unnecessary re-renders either using this approach.
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 can't find any more issues 😆
You make that sound like a bad thing! 😃 Thanks again for the thorough review and all the back-and-forth, @jsnajdr! I can confidently say this was much more complex than I originally thought it would be... 🐇 🕳 |
Changes proposed in this Pull Request
lib/viewport
lib/viewport
lib/viewport/react-helpers
.lib/viewport/react-helpers
hooks and HOCs.Testing instructions
CC @jsnajdr: I think I found a reasonable way of testing hook (and HOC) reactivity. What do you think?