Home > Blockchain >  My use effect is not firing when expected
My use effect is not firing when expected

Time:07-04

I have an "Inbox" page. Depending on the current screen size, I render either a mobile friendly version of the inbox or a desktop version.

Currently my page doesn't render the messages every time, I can see that it's due to my useEffect

Here's the Inbox component:

import { useEffect } from "react";
import { getUserConversations } from "@services/firebase/client/chat-client-services";
import userDataStore from "@stores/UserState/UserStore";
import InboxMessagePreview from "@components/Inbox/InboxMessagePreview/InboxMessagePreview";
import authStore from "@stores/AuthState/AuthStore";
import useSWR from "swr";
import Chat from "@components/Chat/Chat";
import Router, { useRouter } from "next/router";
import useWindowSize from "hooks/useWindowSize";
import { classNames } from "helpers/helpers";
import Skeleton from "@components/UI/Loading/Skeleton/Skeleton";

export default function Inbox() {
  const size = useWindowSize();
  const currentUser = authStore((state) => state.currentUser);
  const userData = userDataStore((state) => state.userData);
  const { data, error } = useSWR(currentUser?.uid, getUserConversations);
  const router = useRouter();

  console.log({ data });
  console.log({ size });

  useEffect(() => {
    if (
      !Router?.query?.chat &&
      data?.conversations?.length > 0 &&
      size.width >= 768
    ) {
      console.log("IN USE EFFECT IF");
      Router.push(
        {
          pathname: `/inbox`,
          query: { chat: data.conversations[0].docID },
        },
        undefined,
        { shallow: true }
      );
    }
  }, [data, size]);

  if (error) {
    <p>Error</p>;
  }

  if (!data) {
    return <InboxSkeleton />;
  }

  if (size?.width < 768 && data) {
    return (
      <MobileChat
        currentUser={currentUser}
        data={data}
        query={router?.query}
        userData={userData}
      />
    );
  }

  if (size?.width >= 768 && data) {
    return (
      <DesktopChat
        currentUser={currentUser}
        data={data}
        query={router?.query}
        userData={userData}
      />
    );
  }

  return null;
}

The console log inside the useEffect does not fire sometimes on page load and therefore I can't see the console log and the messages do not load and a blank page is shown.

My guesses are either the useWindowSize() hook or using Next's Router.

The reason I am using both useRouter and Router is because I use Router inside useEffects. If I use router.push() inside a useEffect, React will warn me that it will need to be added to the dependency array. If I do this, the router will be updated in the useEffect and then it will therefore re-trigger, creating an infinite loop.

The useWindowSize is as follows:

import { useState, useEffect } from "react";
// Define general type for useWindowSize hook, which includes width and height
interface Size {
  width: number | undefined;
  height: number | undefined;
}
function useWindowSize(): Size {
  const [windowSize, setWindowSize] = useState<Size>({
    width: undefined,
    height: undefined,
  });
  useEffect(() => {
    // Handler to call on window resize
    function handleResize() {
      // Set window width/height to state
      setWindowSize({
        width: window.innerWidth,
        height: window.innerHeight,
      });
    }
    // Add event listener
    window.addEventListener("resize", handleResize);
    // Call handler right away so state gets updated with initial window size
    handleResize();
    // Remove event listener on cleanup
    return () => window.removeEventListener("resize", handleResize);
  }, []); // Empty array ensures that effect is only run on mount
  return windowSize;
}

export default useWindowSize;

CodePudding user response:

inside your code you are using in the useEffect Router.push instead of router.push()

CodePudding user response:

Figured out what was wrong.

I did not realise useSWR keys are global. Since I am using the current users UID as the key here, it got data from another component elsewhere that uses the same key, therefore it was getting the wrong data.

  • Related