Files
30-seconds-of-code/snippets/usePortal.md
Chalarangelo a58f4aef39 Fix typos
2022-07-16 17:25:59 +03:00

1.5 KiB

title, tags, expertise, author, cover, firstSeen
title tags expertise author cover firstSeen
React usePortal hook hooks,state,effect advanced chalarangelo blog_images/interior-3.jpg 2022-01-05T05:00:00-04:00

Creates a portal, allowing rendering of children outside the parent component.

  • Use the useState() hook to create a state variable that holds the render() and remove() functions for the portal.
  • Use ReactDOM.createPortal() and ReactDOM.unmountComponentAtNode() to create a portal and a function to remove it. Use the useCallback() hook to wrap and memoize these functions as createPortal().
  • Use the useEffect() hook to call createPortal() and update the state variable any time el's value changes.
  • Finally, return the render() function of the state variable.
const usePortal = el => {
  const [portal, setPortal] = React.useState({
    render: () => null,
    remove: () => null,
  });

  const createPortal = React.useCallback(el => {
    const Portal = ({ children }) => ReactDOM.createPortal(children, el);
    const remove = () => ReactDOM.unmountComponentAtNode(el);
    return { render: Portal, remove };
  }, []);

  React.useEffect(() => {
    if (el) portal.remove();
    const newPortal = createPortal(el);
    setPortal(newPortal);
    return () => newPortal.remove(el);
  }, [el]);

  return portal.render;
};
const App = () => {
  const Portal = usePortal(document.querySelector('title'));

  return (
    <p>
      Hello world!
      <Portal>Portalized Title</Portal>
    </p>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));