Kustemit
Kustemit

Reputation: 105

React Hooks - Removing component after use

I'm trying to wrap my head around this. My custom hook is supposed to create a simple popup with the desired input and remove after 3 seconds. Of course, currently, it re-renders every time the counter has reset. How can I make it render only once and then be removed from the dom?

export function createPopup(content, popupType) {
  const [message, setMessage] = useState(content)
  const [type, setType] = useState(popupType)
  const [value, setCounter] = useState(3)

  const myTimer = setTimeout(() => {
    return setCounter(value - 1)
  }, 1000)

  useLayoutEffect(() => {
    const id = setTimeout(() => {
      setCounter(value + -1);
    }, 1000);

    return () => {
      clearTimeout(id);
    };
  }, [value])

  return (
    <>
      {value !== 0 &&
        <PopupMolecule type={type}>
          {message}
        </PopupMolecule>
      }
    </>
  )
}

Upvotes: 1

Views: 5294

Answers (1)

Don Brody
Don Brody

Reputation: 1727

I think you want something more like this:

export function createPopup(content, popupType) {
  const [visible, setVisible] = useState(true);

  useEffect(() => {
    setTimeout(() => setVisible(false), 3000);
  }, []);

  return (
    <>
      {visible &&
        <PopupMolecule type={popupType}>
          {content}
        </PopupMolecule>
      }
    </>
  )
}

There are still some improvements that need to made here (i.e. fading out on exit or some transition, and the way this is setup you can't use it more than once), but this should fix the problem you stated.

This will show your popup for three seconds on mount, then make your popup invisible and unmount it from the DOM. The empty array in the useEffect hook lets it know to only trigger on mount (and unmount if you return a value). You also don't need the other state variables that you're not updating. Those can just be passed in as function parameters.

Upvotes: 1

Related Questions