{
"$type": "site.standard.document",
"canonicalUrl": "https://ayc0.github.io/posts/blocz-react-responsive-v5-1",
"coverImage": {
"$type": "blob",
"ref": {
"$link": "bafkreiho2cgoujyjx6k2vmfwpyy5mbt4tu5of6umzz253encmsct44pcla"
},
"mimeType": "image/png",
"size": 854391
},
"description": "@blocz/react-responsive v5.1 was just released. Let’s go through all the different features and changes added by this new minor version",
"path": "/posts/blocz-react-responsive-v5-1",
"publishedAt": "2026-06-06T00:00:00.000Z",
"site": "at://did:plc:wifmfjqoxnruni5h62e6zp2y/site.standard.publication/3mn6dj35act2i",
"tags": [
"react",
"news"
],
"textContent": "import LinkToPost from \"@components/LinkToPost.astro\";\n\nAs mentioned in the previous post, going forward @blocz/react-responsive will follow strict semver with new features released in minor versions & deprecations. And major will only be about removals of deprecated features (no added features).\n\n<LinkToPost slug=\"blocz-react-responsive-v5-0\" />\n\nNew features\n\nRenaming\n\nBefore the 5.1.0, the word breakpoint was used to describe the defined _sizes_ available to all our utilities functions. But this name never sat right with me. Why? Because a breakpoint really is just a point, but when you looked at our documentations, we were defining those as ranges:\n\n> | Breakpoint | From | To |\n> | ---------- | ------ | -------- |\n> | xs | 0px | 575px |\n> | sm | 576px | 767px |\n> | md | 768px | 991px |\n> | lg | 992px | 1199px |\n> | xl | 1200px | Infinity |\n\nThe name initially came from bootstrap, so I initially chose it as I thought it made sense to people to explain the concepts. But I don’t think the tradeoff makes sense. And I decided to rename those to \"media ranges\". And this lead to a few renames:\n\n- <BreakpointsProvider> -> <MediaRangesProvider>\n - the breakpoints prop was renamed to mediaRanges\n - the additionalBreakpoints prop was renamed to additionalMediaRanges\n- useBreakpoint() -> useMediaRange()\n- <BreakpointsContext> -> <MediaRangesContext>\n\nOf course, the previous exports were kept without any changes done to them.\n\ncreateMediaRanges()\n\nThe suffered 2 main issues:\n\n- lack of strict typings for breakpoints,\n- hard to use in complex applications.\n\nLack of strict typings\n\nuseBreakpoint() and <Only> allowed you to use invalid breakpoints. The library would fail safely onto false / not rendering its children, but nothing would yell at you in case of typos or invalid values. Which means that this code would be 100% valid:\n\nHard to use in complex applications\n\nDue to the reliance on React contexts, when using multiple sets of breakpoints in the same app, it could be possible – due to conflicts – to have the same component being invalid/valid depending on where it was run.\n\nFor instance, let’s take this component:\n\nVery complex I know 😅.\nNow, if your app relies on defined breakpoint providers, it could behave differently. For instance:\n\nSolution: createMediaRanges()\n\nThose 2 issues led me to create createMediaRanges(). By default, useMediaRange() and <Only> can’t read anymore from any global context, so they’ll always be set to this definition:\n\n| Media range | From | To |\n| ----------- | ------ | -------- |\n| xs | 0px | 575px |\n| sm | 576px | 767px |\n| md | 768px | 991px |\n| lg | 992px | 1199px |\n| xl | 1200px | Infinity |\n\nWhich means that in this example, <MyAwesomeComponent> would always have sm = 576px -> 767px.\n\nNow, where does createMediaRanges() come into play? It allows you to create new connected useMediaRange() and <Only>:\n\nAnd in a full app:\n\nBenefits:\n\n- definitions are 100% stable, from every place in the codebase,\n- no dynamic context, so we can 100% type check it: <Only> & useMediaRange() can throw errors when used with media ranges that aren't the default, and createMediaRanges() can do the same with their custom versions.\n\n:::note[Note]\nAs mentioned before, the 5.1.0 contains no breaking changes. Which means that:\n\n- the providers still exists,\n- <Only> & useMediaRange() still work as before, aka no TS errors and still read from the context.\n\nBut createMediaRanges() has been released and:\n\n- doesn’t rely on the context,\n- is strictly typed.\n\nThe changes to <Only> & useMediaRange() & to the context will come in the v6.0.0.\n:::\n\nDeprecations\n\nRenaming\n\nAs new functions were introduced, but the old ones kept, those are indeed deprecated. This covers:\n\n- useBreakpoint(),\n- <BreakpointsProvider>,\n- <BreakpointsContext>\n\nContext\n\nAs we’re migrating towards createMediaRanges(), all contexts are now deprecated. This covers:\n\n- <BreakpointsContext> (already deprecated by the renaming),\n- <MediaRangesContext> (newly introduced in this version).\n\nIt’s a bit weird to introduce a deprecated API. But this is done so that every renaming could be done in 1 go, and then the migration away from the context could be done too.\n\n<Only> as prop\n\n<Only> contains a prop as that allows you to customize how it’ll be rendered in the DOM. By default, we use Fragment, but if you want it to be a <div> or any other element, you can specify it using the as prop.\nAnd to make this more powerful, any other props can also be passed through:\n\nBut this:\n\n- relies on a deprecated API cloneElement(),\n- is not type safe:\n - impossible to know which props are allowed in this child,\n - can lead to bugs if you pass a prop that isn’t supported at all (like href on custom elements).\n\nIn addition, I find this API 100% useless as we render Fragments. So you can just do this instead:\n\nHow to upgrade\n\nIf you’re already using the 5.0.0, a plain upgrade will work and shouldn’t impact your apps.\nIf you’re using the v4.0.0, as long as you’re not using React version pre-18.0, it should be okay (as the 5.0.0 was just an update of the baseline version of React).\n\nAfter this, you can start using the new APIs as it pleases you.",
"title": "@blocz/react-responsive v5.1"
}