javascriptreactjsreact-hookspopup

useEffect for popup modal


I am currently trying to incorporate a popup modal function which I have managed to do and works however, I am trying to now create that same function inside a useEffect hook so that it does not re-render every time. So far, I have tried several methods and nothing seems to work. Here is my code:

AppContent.jsx (without useEffect):

import React, { useState, useEffect } from 'react'
import { X } from 'lucide-react'
import { AnimatePresence } from 'framer-motion';
import AppForm from './AppForm';

const AppContent = () => {
    const [ applicationOpen, setApplicationOpen ] = useState(false);
    
    const close = () => setApplicationOpen(false);
    const open = () => setApplicationOpen(true);

  return (
    <>
      <button 
        className='apply-btn'
        onClick={() => applicationOpen ? close() : open()}
      >
        APPLY HERE
      </button>
       
      <AnimatePresence>
        {applicationOpen && <AppForm applicationOpen={applicationOpen} handleClose={close}/>}
      </AnimatePresence>
    </>
  )
}

export default AppContent

The code above works just fine.

AppContent.jsx (with useEffect):

import React, { useState, useEffect } from 'react'
import { X } from 'lucide-react'
import { AnimatePresence } from 'framer-motion';
import AppForm from './AppForm';

const AppContent = () => {
    const [ applicationOpen, setApplicationOpen ] = useState(false);
    
    useEffect(() => {
      const close = () => setApplicationOpen(false);
      const open = () => setApplicationOpen(true);

      close();
      open();
    },[]);

  return (
    <>
      <button 
        className='apply-btn'
        onClick={() => applicationOpen ? close() : open()}
      >
        APPLY HERE
      </button>
       
      <AnimatePresence>
        {applicationOpen && <AppForm applicationOpen={applicationOpen} handleClose={close}/>}
      </AnimatePresence>
    </>
  )
}

export default AppContent

Can someone help me please and point out what I am doing wrong? Thank you.


Solution

  • Sticking with the approach you already have, you can use the useCallback hook to create a function that doesn't re-render every time the application updated

    import React, { useState, useCallback } from 'react'
    import { X } from 'lucide-react'
    import { AnimatePresence } from 'framer-motion';
    import AppForm from './AppForm';
    
    const AppContent = () => {
        const [ applicationOpen, setApplicationOpen ] = useState(false);
        
        const close = useCallback(() => setApplicationOpen(false),[]);
        const open = useCallback(() => setApplicationOpen(true), []);
    
      return (
        <>
          <button 
            className='apply-btn'
            onClick={applicationOpen ? close : open}
          >
            APPLY HERE
          </button>
           
          <AnimatePresence>
            {applicationOpen && 
             <AppForm 
               applicationOpen={applicationOpen} 
               handleClose={close}
             />
             }
          </AnimatePresence>
        </>
      )
    }
    
    export default AppContent