skip to Main Content

I need to make my modal persist after website refresh. As soon as a user logs out it refreshes page and modal saying "sign-out successful" disappears. I want the modal to show up after sign-out and persist until the user clicks the close button. I tried to use-effect, but I was likely using it wrong as I am new to react.

"use client";
import "./signinbutton.css";
import { signIn, signOut, useSession } from "next-auth/react";
import Modal from "./Modal";
import React, { useState } from "react";

import { AiOutlineUserAdd } from "react-icons/ai";
import { IoMdLogOut } from "react-icons/io";

const SigninButton = ({ darkMode }) => {
  const [isModalOpen, setIsModalOpen] = useState(false);

  const { data: session } = useSession();
  console.log(session?.user);

  // Function to open the modal
  function logOut() {
    signOut().then(() => {
      setIsModalOpen(true);
    });
  }

  // Function to close the modal
  function closeModal() {
    setIsModalOpen(false);
  }

  if (session && session.user) {
    return (
      <div>
        <button onClick={logOut} className="profile-button">
          <div className="logout-icon">
            <IoMdLogOut
              size={32}
              color={darkMode ? "#ef9726" : "#0099d8"}
            ></IoMdLogOut>
          </div>
        </button>
        <Modal show={isModalOpen} onClose={closeModal}>
          <h2>Successful Signout</h2>
        </Modal>
      </div>
    );
  }

  return (
    <button onClick={() => signIn()} className="profile-button">
      <div className="user-icon">
        <AiOutlineUserAdd
          size={34}
          color={darkMode ? "#ef9726" : "#0099d8"}
        ></AiOutlineUserAdd>
      </div>
    </button>
  );
};

export default SigninButton;
import React from "react";
import "./modal.css"; // You can create a separate CSS file for modal styles if needed.

const Modal = ({ show, onClose, children }) => {
  if (!show) return null;

  return (
    <div className="modal-overlay">
      <div className="modal-content">
        {children}
        <button onClick={onClose}>Close</button>
      </div>
    </div>
  );
};

export default Modal;

2

Answers


  1. Try replacing your useState with custom hook like next (the code is in Typescript, but you can take JS version here):

    export const usePersistentState = <T,>(key: string, initialValue: T) => {
        const [innerState, setInnerState] = React.useState(initialValue);
    
        React.useEffect(() => {
            const lsValue = localStorage.getItem(key);
            const lsValueParsed = lsValue ? JSON.parse(lsValue) : null;
            if (lsValueParsed) {
                setInnerState(lsValueParsed);
            } else {
                setInnerState(initialValue);
            }
        }, [key, initialValue]);
    
        return [
            innerState,
            (newValue: T) => {
                setInnerState(newValue);
                localStorage.setItem(key, JSON.stringify(newValue));
            },
        ] as const;
    };
    
    Login or Signup to reply.
  2. If you need to make the modal persist even after the refresh, then you can use localStorage to do that.

    const KEY = 'SHOW_MODAL';
    
    const Modal = () => {
      const value = localStorage.getItem(KEY);
      const parsedValue = value ? JSON.parse(value) : null;
      
      const [showModal, setShowModal] = useState(parsedValue);
    
      onClose = () => {
         setShowModal(!showModal);
         localStorage.setItem(KEY, JSON.stringify(false));
      }
    
      onOpen = () => {
         setShowModal(!showModal);
         localStorage.setItem(KEY, JSON.stringify(true));
      }
    
      return (showModal ? 
         <div>
           <button onClick={onOpen}>Open</button>
           <button onClick={onClose}>Close</button>
         </div> : null)
    }
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search