Oddly Behaving Conditional Rendering on First Load
See original GitHub issueDescription
Hi gang, in many of my recent projects I’ve employed conditional rendering to render seperate mobile and desktop versions of a component.
The way I achieve this is by adding the following state / logic to my components:
const SMALL_MOBILE_BREAKPOINT = 500;
const MOBILE_BREAKPOINT = 800;
const isClient = typeof window !== 'undefined'; // Prevents breaks when SSR
class Index extends Component {
state = {
viewportWidth: isClient ? window.innerWidth : 0,
};
componentDidMount() {
if (isClient) {
this.updateWindowDimensions();
window.addEventListener('resize', this.updateWindowDimensions);
}
}
componentWillUnmount() {
if (isClient) window.removeEventListener('resize', this.updateWindowDimensions);
}
updateWindowDimensions = () => {
this.setState({ viewportWidth: window.innerWidth });
}
const {
viewportWidth,
} = this.state;
const isSmallMobile = Boolean(viewportWidth <= SMALL_MOBILE_BREAKPOINT);
const isMobile = Boolean(viewportWidth <= MOBILE_BREAKPOINT);
render() {
isMobile ? (
<MobileComponent />
) : (
<DesktopComponent />
)
}
}
I’m seeing some really funky results when I first load the page.
Expected result
My expected result is the specified component renders depending on the window.innerWidth
, as seen in these screenshots:
Mobile
Actual result
What’s really bizarre is that only on the first load of the page, the conditional rendering logic is not applied, components render in their desktop forms which cause a whole lotta issues:
This is happening despite the variables used in the logic correctly evaluating (see console logs):
Though, after I hard refresh the page, everything is back to normal, working as intended.
Steps to reproduce
I’ll try spin up better test environment within the next day, but for the time being I have the project I’m experiencing this issue on to share:
- Load the page for the first time
- To recreate, clear your cookies, cache, deregister service worker and load again.
Additionally, here’s an environment where added some console logs and replaced my own breakpoint logic with react-responsive:
https://deploy-preview-95--carbon8.netlify.com/
If you’ve got the Lighthouse Plugin an easy way to reproduce this (clear your cache, cookies, deregister) is just to run an audit:
Environment
System:
OS: macOS 10.14.5
CPU: (8) x64 Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 11.14.0 - /usr/local/bin/node
Yarn: 1.15.2 - /usr/local/bin/yarn
npm: 6.7.0 - /usr/local/bin/npm
Browsers:
Chrome: 75.0.3770.142
Firefox: 66.0.5
Safari: 12.1.1
npmPackages:
gatsby: ^2.1.19 => 2.9.4
gatsby-image: ^2.0.30 => 2.1.4
gatsby-plugin-canonical-urls: ^2.0.12 => 2.0.13
gatsby-plugin-facebook-pixel: ^1.0.3 => 1.0.3
gatsby-plugin-google-analytics: ^2.0.19 => 2.0.21
gatsby-plugin-lodash: ^3.0.4 => 3.0.5
gatsby-plugin-mailchimp: ^5.1.0 => 5.1.0
gatsby-plugin-manifest: ^2.0.20 => 2.1.1
gatsby-plugin-netlify: ^2.0.11 => 2.0.17
gatsby-plugin-offline: ^2.0.24 => 2.1.3
gatsby-plugin-react-helmet: ^3.0.7 => 3.0.12
gatsby-plugin-robots-txt: ^1.4.0 => 1.4.0
gatsby-plugin-sass: ^2.0.11 => 2.0.11
gatsby-plugin-sharp: ^2.0.23 => 2.1.5
gatsby-plugin-sitemap: ^2.1.0 => 2.1.0
gatsby-plugin-stripe: ^1.2.1 => 1.2.1
gatsby-source-prismic: ^2.2.0 => 2.2.0
gatsby-source-stripe: ^3.0.1 => 3.0.1
gatsby-transformer-sharp: ^2.1.15 => 2.1.21
npmGlobalPackages:
gatsby-cli: 2.4.6
Issue Analytics
- State:
- Created 4 years ago
- Comments:6 (4 by maintainers)
Hey @dzuncoi, my refactor involved reverted to rendering both the mobile version and the desktop version of the component and hiding the inactive component using CSS media queries.
Hi @AllanPooley, what approach do you use to handle refactoring your code? I’m encountering the same behaviour but no luck on trying in many ways 😦