JSFiddle - React, Tailwind, and code Playground

HTML

<button id="elToggle">toggle</button>

<hr />

<div class="block" style="width: 200px; border: 2px solid;" id="elBlock">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellat, voluptatibus, corporis! Impedit nostrum, quibusdam officia alias suscipit totam molestiae magni, vel quos. Tempora perspiciatis animi in qui quod officiis quia.</div>

CSS

.block {
    overflow: hidden;
    transition: height 500ms ease;
}

.is-collapsed {
  height: 0;
}

JavaScript

let isAnimating = false;

function isCollapsed(element) {
	return element.classList.contains('is-collapsed');
}

function onSchedule(fn) {
	/* да, здесь два requestAnimationFrame */ 	
	requestAnimationFrame(function() {
    requestAnimationFrame(function() {
      fn();
    });
  });
}

function open(element) {
	isAnimating = true;
  element.style.height = `${element.scrollHeight}px`;
  onSchedule(function() {
    element.classList.remove('is-collapsed');
    element.addEventListener("transitionend", function onTransitionEnd() {
        element.removeEventListener("transitionend", onTransitionEnd);
        element.style.height = "";
        isAnimating = false;
    });  
  })
}

function close(element) {
	isAnimating = true;
  element.style.height = `${element.scrollHeight}px`;
  onSchedule(function() {
 		element.classList.add('is-collapsed');
    element.style.height = "";
    element.addEventListener("transitionend", function onTransitionEnd() {
    	element.removeEventListener("transitionend", onTransitionEnd);
      isAnimating = false;
    });
  });
}

elToggle.addEventListener("click", () => {
	if (isAnimating) return;
  isCollapsed(elBlock) ? open(elBlock) : close(elBlock);
});