Skip to content
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

Merged
merged 23 commits into from
Mar 4, 2019
Merged

Add hooks and HOCs to lib/viewport #31081

merged 23 commits into from
Mar 4, 2019

Conversation

sgomes
Copy link
Contributor

@sgomes sgomes commented Feb 27, 2019

Changes proposed in this Pull Request

  • Fix a bug in listener removal in lib/viewport
  • Add tests for lib/viewport
  • Add helper hooks and higher-order components to lib/viewport/react-helpers.
  • Add tests for lib/viewport/react-helpers hooks and HOCs.

Testing instructions

  • Ensure that the modified components making use of the helpers still work. It may be difficult to trigger the reactive behaviour for some of them.
  • Ensure the new tests pass.

CC @jsnajdr: I think I found a reasonable way of testing hook (and HOC) reactivity. What do you think?

@sgomes sgomes added [Type] Enhancement [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. labels Feb 27, 2019
@matticbot
Copy link
Contributor

@sgomes sgomes requested a review from a team February 27, 2019 14:52

// Disable console warnings for this file.
// eslint-disable-next-line no-console
console.warn = jest.fn();
Copy link
Contributor

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?

Copy link
Contributor Author

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?

Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, using spies now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks!

Copy link
Member

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.

@sgomes sgomes force-pushed the update/improve-lib-viewport branch from e1d2cfe to eaaca21 Compare February 27, 2019 15:49
@sgomes
Copy link
Contributor Author

sgomes commented Feb 27, 2019

All comments addressed, and several improvements made. Ready for another look.

Copy link
Contributor

@blowery blowery left a 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.

@blowery blowery requested a review from jsnajdr February 28, 2019 17:42
Copy link
Member

@jsnajdr jsnajdr left a 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.

client/components/tooltip/index.jsx Show resolved Hide resolved
client/components/tooltip/index.jsx Outdated Show resolved Hide resolved
client/components/tooltip/index.jsx Show resolved Hide resolved
client/lib/viewport/react-helpers.js Outdated Show resolved Hide resolved
client/lib/viewport/react-helpers.js Outdated Show resolved Hide resolved
client/lib/viewport/react-helpers.js Outdated Show resolved Hide resolved
client/lib/viewport/react-helpers.js Outdated Show resolved Hide resolved
@sgomes
Copy link
Contributor Author

sgomes commented Mar 1, 2019

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 👍

@sgomes
Copy link
Contributor Author

sgomes commented Mar 1, 2019

Thank you for the excellent review as usual, @jsnajdr! 👍

All comments addressed.

client/lib/viewport/README.md Outdated Show resolved Hide resolved
client/lib/viewport/index.js Outdated Show resolved Hide resolved
client/lib/viewport/react-helpers.js Outdated Show resolved Hide resolved
@sgomes
Copy link
Contributor Author

sgomes commented Mar 1, 2019

New comments addressed as well. Thanks again, @jsnajdr !

@sgomes sgomes force-pushed the update/improve-lib-viewport branch from 849a5ab to 128f1f8 Compare March 1, 2019 18:35
@sgomes sgomes force-pushed the update/improve-lib-viewport branch from 128f1f8 to b2ffccb Compare March 4, 2019 10:47
client/lib/viewport/react-helpers.js Outdated Show resolved Hide resolved
client/lib/viewport/react-helpers.js Outdated Show resolved Hide resolved
client/lib/viewport/react-helpers.js Outdated Show resolved Hide resolved
client/components/tooltip/index.jsx Outdated Show resolved Hide resolved
sgomes added 3 commits March 4, 2019 14:40
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.
Copy link
Member

@jsnajdr jsnajdr left a 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 😆

@sgomes
Copy link
Contributor Author

sgomes commented Mar 4, 2019

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... 🐇 🕳

@sgomes sgomes merged commit 7719d45 into master Mar 4, 2019
@sgomes sgomes deleted the update/improve-lib-viewport branch March 4, 2019 16:07
@matticbot matticbot removed the [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. label Mar 4, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants