javascriptreactjsaddeventlistenerreact-transition-group

Where to put callback function in react-transition-group


I want to run a process only after transition has ended.

Here the docs say:

addEndListener

Add a custom transition end trigger. Called with the transitioning DOM node and a done callback. Allows for more fine grained transition end logic. Note: Timeouts are still used as a fallback if provided.

addEndListener={(node, done) => {
  // use the css transitionend event to mark the finish of a transition
  node.addEventListener('transitionend', done, false);
}}

So I use it like this:

<Transition
  addEndListener={(node, done) => {node.addEventListener('transitionend', done, false);}}>
  <MyComponent />
</Transition>

The problem is I don't understand where to put my function to be executed after the transition ended.

If this is my function:

function abc() {
  // blah
  // blah
  //blah
}

Where can I put it? Should I put it in the place of done?


Solution

  • You can use addEndListener, or even onExited and onEntered callbacks.

    With addEndListener:

    function abc() {
      // blah
      // blah
      //blah
    }
    
    ... // some code
    
    <Transition
      addEndListener={(node, done) => {
        const handleTransitionEnd = (e) => {
          abc(e);
          done(e);
          node.removeEventListener('transitionend',handleTransitionEnd,false);
      }
      node.addEventListener('transitionend',handleTransitionEnd, false);
    
        const idTimeout = setTimeout(() => {
                removeItem()
                clearTimeout(idTimeout);
              }, duration)
    }}>
      <MyComponent />
    </Transition>
    

    With onEntered and onExited:

    <Transition
       onEntered={abc} onExited={abc}>
      <MyComponent />
    </Transition>
    
       addEndListener(node, done) {
            const isBack = node.classList.contains('back-exit');
            const isForward = node.classList.contains('forward-exit');
    
            if(isBack || isForward){
              const removeItem = () => {
                
                //onSlideEnd;
                  done();
                // node.removeEventListener('transitionend', removeItem, false)
              }
              // node.addEventListener('transitionend', removeItem, false)
        /*
         if the timeout is greater than 1.5s, the transitionend event is called 
         before the css transition is completed, this is some kind of bug. 
         It is better to use setTimeout
        */
              const idTimeout = setTimeout(() => {
                removeItem()
                clearTimeout(idTimeout);
              }, duration)
            }
          } 
    

    An important thing of the second example: check the moment, when you want to get your callback called.