1

I am using the useWindowDimensions hook in Get viewport/window height in ReactJS to render the sections inside a component conditionally. This component has got 3 sections, when the width of the browser decreases, there will be fewer sections to be shown.

However, sometimes it spits out the "Warning: Did not expect server HTML to contain the text node "Setup" in ." in the console, and the layout of that page is also messed up. This only happens when the page get refreshed. It doesn't happen when I navigate to this page from another page (i.e. no request is sent to the server).

I would like to know why does this happen only in certain scenarios and how to resolve it in general when a component doesn't behave the same way on the client and the server. It's even better if you could explain how to resolve this particular problem gracefully while preserving the intended behaviour of the page.

Here is the code

// useWindowDimensions.ts

import { useState, useEffect } from "react";

function getWindowDimensions() {
  const hasWindow = typeof window !== "undefined";
  const width = hasWindow ? window.innerWidth : null;
  const height = hasWindow ? window.innerHeight : null;
  return {
    width,
    height,
  };
}

const useWindowDimensions = () => {
  const [windowDimensions, setWindowDimensions] = useState(
    getWindowDimensions()
  );

  useEffect(() => {
    function handleResize() {
      setWindowDimensions(getWindowDimensions());
    }

    window.addEventListener("resize", handleResize);
    return () => window.removeEventListener("resize", handleResize);
  }, []);

  return windowDimensions;
};

export default useWindowDimensions;

// TwoSidesMainSection.tsx

import useWindowDimensions from "../../hooks/useWindowDimensions";
import styles from "./TwoSidesMainSection.module.scss";

type Props = {
  leftSection?: React.ReactNode;
  mainSection: React.ReactNode;
  rightSection?: React.ReactNode;
};

const TwoSidesMainSection: React.FC<Props> = ({
  leftSection,
  mainSection,
  rightSection,
}) => {
  const { height, width } = useWindowDimensions();
  const shouldDisplayNoSideSection = width < 800;
  const shouldDisplayAtMostOneSideSection = width < 1250;

  let mainSectionClasses: string = styles.mainSection;

  if (!leftSection && !rightSection) {
    // only main section is supplied
    mainSectionClasses += " " + styles["mainSection-100"];
  } else if (!leftSection || !rightSection) {
    // either left or right section is supplied
    mainSectionClasses += " " + styles["mainSection-75"];
  } else {
    // both left and right section are supplied
    if (shouldDisplayNoSideSection) {
      leftSection = null;
      rightSection = null;
      mainSectionClasses += " " + styles["mainSection-100"];
    } else if (shouldDisplayAtMostOneSideSection) {
      rightSection = null;
      mainSectionClasses += " " + styles["mainSection-75"];
    } else {
      mainSectionClasses += " " + styles["mainSection-50"];
    }
  }
  return (
    <section className={styles.container}>
      {!!leftSection && <div className={styles.sideSection}>{leftSection}</div>}
      <div id={styles.mainSection} className={mainSectionClasses}>
        {mainSection}
      </div>
      {!!rightSection && (
        <div className={styles.sideSection}>{rightSection}</div>
      )}
    </section>
  );
};

export default TwoSidesMainSection;

// SomePage.tsx

const SomePageMainSection = () => {
  return (
    <Fragment>
      <Title>Setup</Title>
    </Fragment>
  );
}


const SomePage = () => {
  return (
    <TwoSidesMainSection
      leftSection={<div></div>}
      mainSection={<SomePageSection />}
      rightSection={<div></div>}
    />
  );
};

export default SomePage;
Stephen Fong
  • 697
  • 5
  • 17
  • Does this answer your question: [Warning: Text content did not match. Server: "I'm out" Client: "I'm in" div](https://stackoverflow.com/questions/66374123/warning-text-content-did-not-match-server-im-out-client-im-in-div)? In your case, the line `typeof window !== "undefined"` is the culprit as it returns different things on the server and client. You shouldn't use it when setting the initial state for `windowDimensions`. – juliomalves Jan 12 '22 at 12:21
  • 1
    Thanks mate, this is exactly the answer I'm looking for. – Stephen Fong Jan 13 '22 at 12:07

0 Answers0