Next.js Discord

Discord Forum

NextUI modal with global state (open from anywhere)

Answered
American black bear posted this in #help-forum
Open in Discord
American black bearOP
I am working on a solution which would make it possible to have (NextUI) Modal codes separated from components, and be able to open any modal from any component of the application. What I'm doing is I created a modal-store where I store the open close state of a modal and its 'type' and a ModalProvider where I just provide all the modals on root layout level. But currently nothing is happening when I open a modal. DO you have any tips? This is my code so far:

ModalProvider:
"use client";

import { useEffect, useState } from "react";
import SignInModal from "../(auth)/signin/sign-in-modal";
export const ModalProvider = () => {
  const [isMounted, setIsMounted] = useState(false);

  useEffect(() => {
    setIsMounted(true);
  }, []);

  if (!isMounted) {
    return null;
  }

  return (
    <>
      <SignInModal />
    </>
  );
};


Modal Store:

import { create } from "zustand";

export type ModalType = "signIn"

interface ModalStore {
    type: ModalType | null;
    isOpen: boolean;
    onModalOpen: (type: ModalType) => void;
    onModalClose: () => void;
}

export const useModal = create<ModalStore>((set) => ({
    type: null,
    data: {},
    isOpen: false,
    onModalOpen: (type) => set({ isOpen: true, type }),
    onModalClose: () => set({ type: null, isOpen: false }),
}));



NavigationBar:
...
const { onModalOpen } = useModal();
...
<Button color="primary" onClick={() => onModalOpen('signIn')}>Sign in</Button>



SignInModal:
  const { isOpen, onModalClose, type } = useModal();
  const isModalOpen = isOpen && type === "signIn";
return (
    <>
    <h1 className='text-red-500'>asdsadasdasdsadasdsadasdasdasd</h1>
      <Modal
        size={"md"}
        isOpen={isModalOpen}
        onClose={onModalClose}
      >
...
Answered by American black bear
<ModalContent>
tag was missing from the Modal Body and without it nextui won't render the modal on the center of the screen
View full answer

10 Replies

ModalProvider is returning what you want to be rendered, but I don't see it being used anywhere

May be more reliable to properly use a context to manage the modal? I've had success with that method.
This way you just have a context that handles the state and a modal component which you render in the root layout
Then for example you can just import in any client component
import { openModal } from "@/context/modalContext"
Brown bear
Why need this code???
useEffect(() => {
    setIsMounted(true);
  }, []);

  if (!isMounted) {
    return null;
  }
I think You dont need this code and ModalProvider
You can just import SignInModal into layout. then would be work
American black bearOP
Solved, thanks for help!
@American black bear Solved, thanks for help!
What is the solution?
@joulev What is the solution?
American black bearOP
<ModalContent>
tag was missing from the Modal Body and without it nextui won't render the modal on the center of the screen
Answer