-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
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
[useMediaQuery] Accept function as argument & more #16343
Conversation
@oliviertassinari Shouldn't |
Details of bundle changes.Comparing: 783b693...2d84f2d
|
IMO it's probably fine as it is now. I guess it could be placed in its own folder but it's just Plus moving it might be a breaking change depending on imports. |
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 have to admit, I shouldn't have added useMediaQueryTheme
in the documentation. It was rushed.
The module isn't exported anywhere, nor present in any demo. People can find it searching in the source. We also have one reference of its existence in the documentation. People importing it break the tree-sharking rule (depth > 2), they most likely bundle the cjs and esm transitive dependencies of the module. That's not great.
It would be great to get it right this time! One possible strategy:
- We could merge the current
useMediaQueryTheme.js
logic intouseMediaQuery.js
. I wouldn't expect any significant bundle size increase. The theme has no default value. Regarding the naked version of the library, we would expose a hook factory where people can provide their own theme context. - Do we need to expose a version of the hook with the default theme cc @fzaninotto? If we do (most likely), then maybe we should have a separate new public
useMediaQueryTheme
module.
34d6e03
to
ca6665b
Compare
I totally agree to merge If the theme has no default value, there needs to be an escape hatch for the function version, because if a developer calls |
@fzaninotto I don't think that |
@joshwooding Based on its location it's considered a private component, but technically yes, it would be. |
Before we move forward in any direction. I would propose that we take a step back by taking a holistic point of view. We could potentially improve this hook in the following areas:
useMediaQuery('(min-width:600px)') We could support an object syntax: useMediaQuery({ minWidth: 1000 }); The bundle overhead seems minimal: https://github.com/streamich/use-media/blob/3093c39a2ac119738f887c43d503ddfa77f8c6d3/src/index.ts#L8-L25. Should we support it outside of the box rather than documenting a usage example with
@merceyz Yes, I agree. But we mention its existence at one place in the docs. What do you guys think of:
|
What's that? CSS media queries already support chaining multiple queries.
What would be the advantages here? Why do we need it in the core?
It's one tiny import. I think we that we can live with it.
I think this shouldn't be a hook that's used on the server. Media queries make no sense on the server. It should rather be implemented in application code where a default bundle is shipped and then adjusted on the client. People need to be aware that changing layout of a server-side rendered app with client side logic will cause flash of unstyled content (or rather "wrongly styled content"). |
Yes, media queries support logic. The multi-media query feature is only interesting for batching the updates. #16460 explore the interest of this feature. Assuming you need to do: const a = useMediaQuery('(min-width: 100px)');
const b = useMediaQuery('(max-width: 150px)'); what if you could write instead: const [a, b] = useMediaQuery(['(min-width: 100px)', '(max-width: 150px)']); and only re-render once when a media query match changes? I believe that the update batching only works because React deduplicates the state updates of the same useState hook (B.). It doesn't work when the state is in two different useState hooks (A.). Now, the only close to an "acceptable" use case we have for it is the withWidth. It's why I'm reluctant to make it public and hopefully remove it. None of the alternative implementations I can benchmark support it:
It's a feature request I have seen from people, I wish I have kept the source of it! I can imagine that it can be more convenient than using a string template with variables. I don't have a strong conviction that it's very valuable. https://github.com/streamich/use-media supports it. Maybe we should wait for further requests with a strong case?
It's fundamentally impossible to perform media queries server side, correct. The server has some information on what the client will look like when rendering its response but not enough. People can use heuristics on the user-agent or leverage client hints. It's these cases that I think we should try to better support.
How can we help them minimize the wrongly styled content (avoiding wrong intermediate state)? |
Needs benchmark showing that one is faster than the other. A render call is nothing inherently slow. Quite the opposite. Don't get me wrong it's not like this is very complicated and adds a lot of maintenance burden. I just want to avoid further propagating that you should care about the number of render calls. You really don't and if they are an issue than you should look into your render call. Are media queries even that time sensitive? Do I really need to have 60fps while resizing my window?
I don't think we can. There's just an inherent disconnect between the static markup being rendered and javascript being evaluated/executed |
In #16460, the issue is with the consistency of the data.
Assuming that 70% of the media query usage is about width responsiveness and that 70% of the browsers support width client hint. What prevents us from helping people to solve the issue? |
In that case I feel using objects would be easier to read/use + autocomplete |
There are plenty of tooling available to filter noise. If you want to listen for it then that is your issue. Again: a render is not important. A commit might be but even then: Fix your tooling and filter the noise of commits below 16ms.
Makes sense. Though I sense there is a different issue here with how the intervals are constructed. We have to be aware that we're kind of abusing media queries to read the current screen width. They were not really intended to do that. |
Regarding the logging aspect, my assumption was that the majority of the people use console.log and that it's not likely to change. |
0781413
to
3feedc0
Compare
3feedc0
to
5718bf6
Compare
5718bf6
to
4c9b3a7
Compare
function useMediaQuery(queryInput, options = {}) { | ||
const multiple = Array.isArray(queryInput); |
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.
remove multiple support
@oliviertassinari Wouldn't it be better if |
@merceyz Yes, I think that we could have two versions in the future:
Something for the coming months :), for now, I think that core without the default theme is our best option. |
7247ac4
to
b6003dd
Compare
Closes #16313
Closes #15187
Closes #16073
Closes #16580