How to use a different delay for each item with React transition group?

10,602

I solved my issue by adding a transitionDelay in the style of my ItemPreview as well as changing the timeout dynamically for each item.

The tricky part is to calculate the actual delay for each item, especially when loading new items afterwards. I ended up adding a isNew field in my items in the reducer which is set to true only for newly loaded items. This is not ideal as it involves changing my data just for animations.

render(){
    const { items } = this.props;
    let delay_index = -1;
    let delay_jump = 100;
    return (
        <TransitionGroup>
            items.map((item,index) => { 
                delay_index += offer.isNew ? 1 : 0;
                const delay = Math.max(0, delay_index*100);

                return (
                    <CSSTransition
                        key={item.id}
                        timeout={1000 + delay}
                        classNames="fade">
                            <ItemPreview
                                item={item} 
                                style={{transitionDelay: `${delay}ms`}} />             
                    </CSSTransition>
                )
            })
        </TransitionGroup>
    )
}
Share:
10,602

Related videos on Youtube

nbeuchat
Author by

nbeuchat

I am one of four co-founders at Alpaca, an AI startup that helps people find a place to live through AI and social media. I am also passionate about machine learning, natural language processing, chatbots, and data visualization. Feel free to check out our website, we may have job openings: https://rentalpaca.com And if you need an apartment, check our website as well!

Updated on September 14, 2022

Comments

  • nbeuchat
    nbeuchat over 1 year

    I am animating the entry and exit of an array of items using TransitionGroup and CSSTransition (with a fade effect). I would like the items to appear with a slight delay between them instead of all at the same time. Note that the delay can be lower than the duration of the animation.

    With my current code, all the items are fading-in at the same time (as expected). In my render function, I have the following to animate the entry and exit of my components:

    <TransitionGroup>
        items.map((item,index) => ( 
            <CSSTransition
                key={item.id}
                timeout={1000}
                classNames="fade"
                    <ItemPreview item={item} />
             </CSSTransition>
        ))
    </TransitionGroup>
    

    And the CSS:

    .fade-enter{
        opacity: 0;
        visibility: hidden;
        transition: all ease 1s;
    }
    
    .fade-enter.fade-enter-active{
        opacity: 1;
        visibility: visible;
        transition: all ease 1s;
    }
    
    .fade-exit {
        visibility: visible;
        opacity: 0;
    }
    
    .fade-exit.fade-exit-active{
        opacity: 0;
        visibility: hidden;
        transition: all ease 1s;
    }
    

    How would I go about adding a different delay for each item?