Search code examples
next.jscomponentsstate

How to prevent component unmounting/remounting on nextjs


In my nextjs 14 app I have a Chat component that shouldn't unmount/remount. The issue is that on my mobile screen I created a button that expands the chat and a button to close the chat. When I expand/close the Chat, the component is being destroyed and re-rendered and I loose the conversation. Is there a way to avoid this from happening ?

This is my code:

//Brakpoints
    const FirstRoot = styled(Paper)(({ theme }) => ({
      marginInline: theme.spacing(0.5),
      overflowY: "auto",
      [theme.breakpoints.down("md")]: {
        height: "100%",
        width: "100%",
      },
      [theme.breakpoints.between("md", "lg")]: {
        height: "100%",
        width: "70%",
      },
      [theme.breakpoints.up("lg")]: {
        height: "100%",
        width: "70%",
      },
    }));


//Chat container
    interface ChatContainerProps {
      isChatOpen: boolean;
    }
    
    const ChatContainer = styled(Box)<ChatContainerProps>(({ isChatOpen }) => ({
      position: "fixed",
      top: 0,
      left: 0,
      width: "100%",
      height: isChatOpen ? "100vh" : 0,
      display: isChatOpen ? "block" : "none",
      backgroundColor: "white",
      zIndex: 1201,
    }));
    
    ...

//Open/close states
    const [isChatOpen, setIsChatOpen] = useState(false);
    
      const toggleChat = (): void => {
        setIsChatOpen((prevState) => !prevState);
      };
    
    ...
    
    <FirstRoot>
            {children}
            {!isChatOpen && (
              <Box
                sx={{
                  display: { xs: "block", sm: "block", md: "none" }, //Chat is displayed only on mobile
                  zIndex: 1201,
                  position: "fixed",
                  bottom: 25,
                  right: 16,
                  borderRadius: "50%",
                  overflow: "hidden",
                }}
              >
    //Image is the button to open Chat component
                <Image
                  alt="Open Chat"
                  height={80}
                  onClick={toggleChat}
                  src="/kerry_avatar.png"
                  style={{ cursor: "pointer" }}
                  title="Open Chat"
                  width={80}
                />
              </Box>
            )}
    //IF isChatOpen is true it opens the Chat component
            {isChatOpen ? (
              <Box
                sx={{
                  display: { xs: "block", sm: "block", md: "none" },
                }}
              >
                <ChatContainer isChatOpen={isChatOpen}>
                  <Chat onClose={toggleChat} /> //onClose closes the chat Component
                </ChatContainer>
              </Box>
            ) : null}
          </FirstRoot>

Solution

  • you should not use useState because when you change the value of it , it will re-render the component , try to hide the chat and show it using useRef with js code