Hiding or showing a element with React is as simple as an if statement deciding whether to print it or not. However often you want to be able to animate the transition, so that it smoothly closes or opens. To avoid cluttering the various components with this animation logic, extract the logic into a hook:

 * Returns the variables needed to animate a open and close functionality via height
 * @param  {Boolean} isOpen:   boolean is the element initially open
 * @param  {Number}  duration: number duration in ms
function useHeightAnimation(isOpen = false, duration = 350) {
  const contentRef = React.useRef(); // Inner wrapper that keeps the height if the outer animated is closed
  const [height, setHeight] = React.useState(isOpen ? 'auto' : 0);

  const handleClick = () => {
    const contentRect = contentRef.current.getBoundingClientRect();

    // Set the height so the element has an initial height to transition from

    // Set the new desired height, either 0px or full height from the innerRef
    setTimeout(() => setHeight(height === 0 ? `${contentRect.height}px` : 0));

      () => {
        if (height === 0) {
          // Set the height to "auto" to prevent issues with resizing when fully opened

  return { height, handleClick, contentRef };

The hook can be used like:

function MyComp(props) {
  const duration = 350;
  const { height, handleClick, contentRef } = useHeightAnimation(false, duration);

  return (
      <button onClick={handleClick}>Open or close</button>
          height: height,
          overflow: height === 'auto' ? 'visible' : 'hidden',
          transition: `height ${duration}ms cubic-bezier(0.4, 0, 1, 1)`,
        <div ref={contentRef}>
          Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore
          et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
          cillum dolore eu fugiat nulla pariatur.