reactjsreactcsstransitiongroup

CSSTransitionGroup replacing


I'm trying to make it so that the client can see a sliding in and out whenever a content is replaced on the DOM. It will just switch out the src of the image inside of the CSSTransitionGroup.

            <CSSTransitionGroup
                component='div'
                className='image-container'
                transitionName='slide-in'
                transitionEnterTimeout={500}
                transitionLeaveTimeout={500}
            >
                {this.props.name?<img src={this.state.img}/>:null}
            </CSSTransitionGroup>

Since the img is not being removed once it's mounted, the Leave action does not seem to fire. What's the approach into making it so that the Leave fires on an element replacement?


Solution

  • As you deduced, the inner element(s) of a CSSTransitionGroup need to be mounted or unmounted in order for it to work. It's not sufficient to simply change a property on the element(s).

    Fortunately, there is a neat trick you can use that doesn't involve actually mounting or unmounting your inner components. CSSTransitionGroup uses the key property to identify elements and determine when they need to be cloned and/or animated. key should be a unique identifying string of some sort, and if that key string changes, then as far as CSSTransitionGroup is concerned you have just unmounted a component.

    Try this:

            <CSSTransitionGroup
                component='div'
                className='image-container'
                transitionName='slide-in'
                transitionEnterTimeout={500}
                transitionLeaveTimeout={500}
            >
                {this.props.name?<img key={this.state.img} src={this.state.img}/>:null}
            </CSSTransitionGroup>
    

    Now when this.state.img changes, it should change the key property and trigger an animation.

    Note: You should ALWAYS use the key prop on the elements inside of CSSTransitionGroup, even when you're not using this "trick". CSSTransitionGroup needs that prop on its children in order to function correctly.

    From the docs:

    You must provide the key attribute for all children of ReactCSSTransitionGroup, even when only rendering a single item. This is how React will determine which children have entered, left, or stayed.