-
Notifications
You must be signed in to change notification settings - Fork 115
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 implementation #149
Add hooks implementation #149
Conversation
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.
See comments. Please let me know if they're unclear, or if there's additional explanation desired.
@@ -3,18 +3,19 @@ | |||
"env": { | |||
"browser": true | |||
}, | |||
"plugins": ["import", "react"], | |||
"plugins": ["import", "react", "react-hooks"], |
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.
There's a separate ESLint plugin for the rules of hooks, which will be nice for anyone working on this library.
import PropTypes from "prop-types"; | ||
import invariant from "invariant"; | ||
import json2mq from "json2mq"; | ||
|
||
import MediaQueryListener from "./MediaQueryListener"; | ||
|
||
const queryType = PropTypes.oneOfType([ |
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.
Pushed these down to live with the new location for propTypes.
PropTypes.object, | ||
PropTypes.arrayOf(PropTypes.object.isRequired) | ||
]); | ||
const checkInvariants = ({ query, queries, defaultMatches }) => { |
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.
There wasn't a strong reason to pull this out into a separate function - it mostly just seemed noisy in the constructor.
!(!props.query && !props.queries) || (props.query && props.queries), | ||
'<Media> must be supplied with either "query" or "queries"' | ||
); | ||
const wrapInQueryObject = query => ({ __DEFAULT__: query }); |
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.
Moved this and unWrapSingleQuery
up to the top, since I refactored them as arrow functions. Again, that's more a stylistic preference; if there's a strong reason to leave them as functions I can refactor.
const result = this.queries.reduce( | ||
export const useMedia = ({ query, queries, defaultMatches, targetWindow, onChange }) => { | ||
checkInvariants({ query, queries, defaultMatches }); | ||
const activeQueries = useRef([]); |
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.
This provides a stable location for the media queries to live from render to render. I could have used state for this as well, but I figured that since there isn't logic to change query
or queries
from render to render, having logic to make activeQueries
change from render to render wouldn't have made sense.
Actually, now that I think about it, was it an intentional design decision to not allow for the quer(y/ies) props to change from render to render, e.g. in a componentDidUpdate
? I can refactor if that would be desired behavior.
@@ -39,33 +39,32 @@ | |||
"@babel/plugin-transform-runtime": "^7.1.0", | |||
"@babel/preset-env": "^7.1.6", | |||
"@babel/preset-react": "^7.0.0", | |||
"@rollup/plugin-babel": "5.0.0", |
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.
npm audit
complained about rollup-plugin-snapshot-size
and upgraded it beyond a version that worked with the current version of rollup
, so I upgraded Rollup and all its friends.
import { sizeSnapshot } from 'rollup-plugin-size-snapshot'; | ||
import { uglify } from 'rollup-plugin-uglify'; | ||
import { terser } from 'rollup-plugin-terser'; |
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.
Uglify became Terser. These are otherwise functionally identical packages.
@@ -18,35 +18,35 @@ function external(id) { | |||
const cjs = [ | |||
{ | |||
input, | |||
output: { file: `cjs/${pkg.name}.js`, format: 'cjs' }, | |||
output: { file: `cjs/${pkg.name}.js`, format: 'cjs', exports: 'named' }, |
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.
Rollup wants you to be explicit about named exports when you're providing both a default and named export. It still complains if you provide both a default and a named export, but we're ignoring that for now.
external, | ||
plugins: [ | ||
babel({ exclude: /node_modules/ }), | ||
babel({ exclude: /node_modules/, babelHelpers: 'bundled' }), |
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.
The new version of the babel plugin uses a different setting for whether to include the babel runtime, so this changed throughout the fiel.
.size-snapshot.json
Outdated
}, | ||
"webpack": { | ||
"code": 4345 | ||
"code": 3673 |
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.
Check it out! We're actually getting a smaller package out of this.
}, | ||
"dependencies": { | ||
"@babel/runtime": "^7.2.0", | ||
"@babel/runtime": "^7.9.6", |
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.
Will this cause problems? Or will it just ensure that the runtime required by an end-user ends up being at least this recent?
I was running into this error:
And couldn't figure out what to make of it. I found a bunch of issues that talked about it:
but none of the fixes detailed in those issues seemed to work. I tried swapping Any objections to using Yarn? |
This should be ready for review now. |
Good catch on trying yarn. I suppose there is some locked package that imports the wrong babel version for some reason. So I deleted the I actually think library authors shouldn't use
|
Pinging @mjackson to give him a chance to review this if he has time. If he doesn't jump in we'll release an alpha soon. |
Ah, yeah. Looks like you're correct about lockfiles: https://dev.to/gajus/stop-using-package-lock-json-or-yarn-lock-3ddi I'll remove the lockfile from this PR and see how it works. I'll also do some research on silencing that error. I think it's in that test case that's designed to throw, and there's probably something I need to do in Jest to make sure that the error is fully caught. |
I've made both of those changes. I think there's some additional refactoring and simplification that could be done, but I'd be okay with leaving that for future work. |
Hey man, just letting you know I haven't forgotten about this! Life a bit hectic ATM, I'll do my best to squeeze this in ASAP. |
No worries! You've already been more present and responsive than multiple projects that I've submitted PRs to in recent months. Thank you! |
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.
This looks good, thank you so much man. There are a two points of improvements that we should add, but I want to merge this in and release an alpha tag anyway. I'll open a new issue (#150) for the improvements:
- Add tests for
useMedia()
- Add documentation for
useMedia()
- Add types to
index.d.ts
foruseMedia()
Now available at It would be great if some people could test it out on their codebases and report back any issues 🙏 |
great great news ! |
Fixes #148
Motivation
This has been requested functionality for a while now and I found the time to get around to it.
Changes
I'll annotate the files, since this diff is pretty noisy.
Notes
I'm not entirely sure that the two-pass SSR render behavior has been preserved. I'd love some help figuring that out in code review.
This should be released as a major version according to semantic versioning rules because peer dependencies are changing. It also ended up being a pretty major rewrite.