You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We're calling `createResponsiveSystem` with our own custom breakpoints, and we get back a `ScreenClassProvider` (keeps track of the current screen class), and a hook called `useResponsiveValue` (creates a value that changes based on the screen class). We also provided a `defaultScreenClass` so that Responsive System knows which screen class to use when it can't find a `window` to measure (e.g. during SSR or headless testing). We immediately export everything so that we can import it across our app.
76
+
We're calling `createResponsiveSystem` with our own custom breakpoints, and we get back a `ScreenClassProvider` (keeps track of the current screen class), and a hook called `useResponsiveValue` (creates a value that changes based on the screen class). Then, we export everything so that we can import it across our app.
78
77
79
78
### 3. Render the ScreenClassProvider near the root of your app
80
79
@@ -172,12 +171,57 @@ If you'd like to enable desktop/mobile-first cascading, you can pass the `cascad
Server-Side rendering is a bit tricky because we don't have access to the user's device to measure their screen. Because we can't automatically determine the proper screen class during SSR, you must "manually" provide an `initialScreenClass` for Responsive System to render.
initialScreenClass:'lg', // only add this if you're doing Server-Side Rendering
186
+
});
187
+
```
188
+
189
+
Now here's the downside: if you guess the initial screen class incorrectly, your users may see a quick flash of the wrong layout before React kicks in (hydrates the app) and adjusts to the proper screen class. In order to avoid that experience, you have a few options:
190
+
191
+
### Don't SSR
192
+
193
+
This is the easiest approach. If you don't SSR, then you don't have to worry about manually figuring out the initial screen class. We can figure it out for you and we can make sure that there's no flash of an incorrect screen class
194
+
195
+
### Client-Only Components
196
+
197
+
You can render some placeholder content (like a spinner/skeleton/glimmer) during SSR and then render the correct content once the code gets to the client. Showing a loading experience is better than showing an incorrect layout and then shifting it.
198
+
199
+
Here's a quick implementation that you could use to render a placeholder on the server:
200
+
201
+
```jsx
202
+
functionClientOnly({ placeholder, children }) {
203
+
constisOnClient=useRef(false);
204
+
useEffect(() => {
205
+
// useEffect only runs on the client
206
+
isOnClient.current=true;
207
+
}, []);
208
+
// will return `placeholder` on the server and `children` on the client
209
+
returnisOnClient.current? children : placeholder;
210
+
}
211
+
// usage
212
+
<ClientOnly placeholder={<PlaceholderContent />}>
213
+
<ResponsiveComponent />
214
+
</ClientOnly>;
215
+
```
216
+
217
+
### Smart Server
218
+
219
+
This route is tricky, but if you want to try it, here are some ideas:
220
+
221
+
- At a minimum you can check the User-Agent Request header to get an idea of what type of device is being used (mobile vs laptop/desktop) and use that info to make an educated guess.
222
+
- If your user is navigating from page to page in your app and you control the links, you could append width and height query params to each request before it goes out. The first page they hit wouldn't have the query params, but all subsequent pages would. And it's technically possible for someone to resize their screen after they click a link, so it's not bulletproof.
223
+
224
+
## Extras
181
225
182
226
### `useScreenClass` Hook
183
227
@@ -190,7 +234,7 @@ Want direct access to the screen class itself? Sure! We're already providing it
190
234
191
235
exportconst {
192
236
ScreenClassProvider,
193
-
responsive,
237
+
useResponsiveValue,
194
238
useScreenClass, // export the hook
195
239
} =createResponsiveSystem(...);
196
240
@@ -205,10 +249,6 @@ const Button = props => {
205
249
};
206
250
```
207
251
208
-
## Server-Side Rendering
209
-
210
-
If `react-responsive-system` cannot access the `window`, it will use the `defaultScreenClass` that you set in the configuration object. When the code is re-hydrated on the client, it will adjust to the actual screen class.
211
-
212
252
## Under the Hood
213
253
214
254
For folks who are curious about the implementation:
@@ -233,9 +273,17 @@ So the middle number actually represents a major breaking change for v0 versions
233
273
234
274
In this section, we'll cover those major changes so that folks can decide whether or not they want to update.
235
275
236
-
### v0.9
276
+
### v0.10 - Server-Side Rendering support
277
+
278
+
In this update we focused on supporting server-side rendering (SSR). Fundamentally, we don't have access to the user's screen during server rendering, so we can't automatically determine the proper screen class for the server-rendered content.
279
+
280
+
In order to continue to provide an optimal client-side rendering experience while also supporting a bug-free server-side rendering experience we made `defaultScreenClass` optional and we also renamed it to `initialScreenClass` to make its purpose more clear. Making it optional allows us to dynamically decide whether to use our client-side optimized implementation or to switch to the server-side optimized implementation.
237
281
238
-
There are significant breaking changes between the 0.8.X and 0.9.X lines. With that said, the 0.8.X line went for 2+ years with no major changes and is quite stable, so there's really not much reason to upgrade if it's working for your project!
282
+
IMPORTANT: if your app is client-side only, don't include `initialScreenClass` in your setup! We'll automatically determine the initial screen class and ensure that the content renders properly (without shifting). If you provide an `initialScreenClass` and it's incorrect, your users might see your components shift from one screen class to another when they load the page.
> Note: the 0.8.X line went for 2+ years with no major changes and is quite stable, so there's really not much reason to upgrade if it's working for your project!
239
287
240
288
The reason that we haven't moved to 1.0 yet is that the API just hasn't felt quite right. It was a bit clunky and there were a few hacks behind the scenes to get it to work the way that we wanted it to work. 0.9 eliminates those hacks, improves the performance, and generally gets much closer to what we feel could be worthy of 1.0; the downside is that we needed to make some fundamental (breaking) changes.
It's quite difficult to gather community feedback for a change like this, but we're very interested to hear how y'all feel about the change. Did you love the old API? Should we continue to support it? Do you have a use case where the new API falls short? Feel free to reach out on Twitter (@ejhammond) or to file an issue to start a discussion!
0 commit comments