reactjs/react-transition-group

SwitchTransition with "out-in" and possible null item?

simonhrogers opened this issue · 1 comments

I’d like to transition a group of elements with mode="out-in", but there will often be no element to display.

What is the correct way to accommodate for the possibility of no element? I’ve tried doing it like so below, which was working well but of course from the "empty" element you actually need to switch the transition mode to "in-out", or there will be a 500ms delay while the empty element is transitioned out. This looks weird!

So I thought I could change the transition mode below, by setting previousActiveProject in state, but changing the transition mode occasionally seems to yield no transition being run at all – the element will just disappear immediately with no fade.

Thanks so much for any help on this!

<div className={`index-section-item-image index-section-item-project-image`}>
  <SwitchTransition mode={previousActiveProject ? "out-in" : "in-out"}>
    <CSSTransition
      key={!activeProject || isScrolling ? 'empty' : activeProject._id}
      addEndListener={(node, done) => node.addEventListener("transitionend", done, false)}
      classNames='fade'
    >
      {!activeProject || isScrolling ? (
        <div className="empty"></div>
      ) : (
        <SanityImage
          key={`${activeProject._id}-image`}
          image={activeProject.image}
          sizes={['25vw','25vw','25vw','25vw']}
        />
      )}
    </CSSTransition>
  </SwitchTransition>
</div>

This was how I handled my case which is slightly different than yours, I know which thing is being hovered and if it's being hovered or not.

<SwitchTransition mode="out-in">
  {/* This is required to not leave an always showing card... stupid... */}
  {isProductHovered ? (
    <CSSTransition key={product.id} timeout={300} classNames="fade">
      <div className={`product-info`}>
        <div className="product-info__content">
          <div className="product-info__image">
            <img src={product.featuredImage} alt={product.title} />
          </div>
          <div className="product-info__name">{product.title}</div>
          <div className="product-info__description">
            {product.description}
          </div>
        </div>
      </div>
    </CSSTransition>
  ) : (
    <CSSTransition key="empty" timeout={300} classNames="fade">
      <div> </div>
    </CSSTransition>
  )}
</SwitchTransition>