How to use useEffect to add and remove event listeners

44 Views Asked by At

I'm building RichText editor using Tiptap and one of my buttons is preview button. Once I click it, a modal with the preview appears. The content of this modal is an HTML coming from my editor. Additionally, once the modal appear, what I want to do is to add event listeners to specific parts of the preview. I'm trying to use useEffect with open as a dependency, but when it's called, the ref is empty and hence listeners are not added. Here is my code (using Shadcn for Modal):

type Props = {
  editor: Editor;
};

export const PreviewButton = ({ editor }: Props) => {
  let pathname = usePathname();
  let [open, setOpen] = useState(false);
  let [lastContent, setLastContent] = useState(<div></div>);
  let ref = useRef<HTMLDivElement>(null);

  let handleClick = () => {
    console.log(pathname);
    setOpen(true);
    return true;
  };

  useEffect(() => {
    let handleClick = () => console.log('Hi');
    // let content = document.getElementById('#preview') as HTMLDivElement;
    let content = ref.current!;
    if (open) content.addEventListener('click', handleClick);
    return () => content?.removeEventListener('click', handleClick);
  }, [open]);

  let content = open ? (
    <div
      style={{ maxWidth: '800px' }}
      id='preview'
      className='ProseMirror prose dark:prose-invert'
      dangerouslySetInnerHTML={{ __html: editor.getHTML() }}
    ></div>
  ) : (
    lastContent
  );

  let onOpenChange = () => (open: boolean) => {
    open ? editor.setEditable(false) : editor.setEditable(true);
    !open && setLastContent(content);
  };

  let modalContent = (
    <DialogContent ref={ref}>
      <DialogHeader>
        <DialogTitle>Podgląd</DialogTitle>
      </DialogHeader>
      {content}
    </DialogContent>
  );

  return (
    <MenuButton
      icon={<PreviewIcon />}
      command={handleClick}
      tooltip={{
        content: <TooltipContent title={_t('commands.preview')} />,
      }}
      modal={{
        isModalButton: true,
        modalContent: modalContent,
        isOpen: open,
        setIsOpen: setOpen,
        onOpenChange: onOpenChange,
      }}
    />
  );
};

I want to remove all listeners once the modal is closed and add them again once the modal is opened again because the content will be different. Adding ref to dependency array doesnt work as well

0

There are 0 best solutions below