title: changing state in asynchronous function call back has unexpected results
body: <p>I am trying to implement an alerts system in my app where the component <code>AlertBox</code> contains a list of alerts that are removed after 10 seconds after an animation has finished or by pressing the close button I pass a <code>closeFunction</code> as a prop to be called with the alerts id the close function works just fine but the call back one behaves weird here is the code</p>
  <p>the next.js route for testing the component</p>
  <pre class="lang-js prettyprint-override"><code>export default function() {
  
      const [alerts , setAlerts] = useState([Math.random()])
  
      return &lt;AlertBox alerts={alerts} setAlerts={setAlerts} &gt;&lt;/AlertBox&gt;
  }
  </code></pre>
  <p>alerts-box component</p>
  <pre class="lang-js prettyprint-override"><code>// not implemented yet
  function getLevelColor(level) {
      return 'blue';
  }
  
  function Cross({className , onClick , aurguments}) {
      return (
          &lt;div onClick={e =&gt; onClick(aurguments)} className='cross-container-full w-5 h-5 absolute  left-3 flex justify-center hover:cursor-pointer' 
          style={{alignItems:'center'}} &gt;
              &lt;div style={{backgroundColor:'#7d7d7d'}} className='w-4 h-1 rotate-45 absolute' &gt;&lt;/div&gt;
              &lt;div style={{backgroundColor:'#7d7d7d'}} className='w-4 h-1 -rotate-45 absolute' &gt;&lt;/div&gt;
              &lt;div&gt;&lt;/div&gt;
          &lt;/div&gt;
      )
  }
  
  function Alert({message , level , finishCallback , id , top}) {
  
      const color = getLevelColor(level);
      const [state , setState] = useState('full');
  
      const animate = useCallback(div =&gt; {
          
          if(!div) {
              return;
          }
  
          const animation = div.animate([
              {
                  width:'100%',
              },
              {
                  width:'0px',
              }
          ] , 4000);
  
          div.parentElement.animate([
              {transform:'translateX(0rem)'}
          ] , 200).onfinish = e =&gt; {
              div.parentElement.className = div.parentElement.className.replace('-translate-x-96' , '');
          }
  
          animation.onfinish = e =&gt; {
              finishCallback(id);
          };
  
      } , []);
  
      return (
          &lt;div className={`w-96 h-12 mb-5 bg-p4 relative -translate-x-96`}
          style={{display:'flex',flexDirection:'column',justifyContent:'center'}} &gt;
              &lt;p className='mr-5' style={{direction:'rtl'}} &gt;{message}&lt;/p&gt;
              &lt;Cross onClick={finishCallback} aurguments={id} className='w-2 h-2'&gt;&lt;/Cross&gt;
              &lt;div ref={animate} className='w-full h-1 bg-p3 block absolute bottom-0'
               &gt;&lt;/div&gt;
          &lt;/div&gt;
      )
  
  };
  
  export default function AlertBox({alerts , setAlerts}) {
  
      const finishCallback = id =&gt; setAlerts(alerts.filter(alert =&gt; alert !== id));
  
      return (
          &lt;&gt;
          &lt;div className='mt-24 ml-12 overflow-hidden relative' &gt;
              {alerts.map((alert , i) =&gt; &lt;Alert
              message=&quot;my message to you&quot;
              id={alert}
              key={alert}
              finishCallback={finishCallback}
                 &gt;&lt;/Alert&gt; ) }
          &lt;/div&gt;
          &lt;button onClick={() =&gt; setAlerts([...alerts , Math.random()])} &gt;
              click
          &lt;/button&gt;
          &lt;/&gt;
      )    
  
  };
  </code></pre>
  <p>and here is the <a href="https://codesandbox.io/s/agitated-chebyshev-cqxr4e?file=/src/App.js" rel="nofollow noreferrer">link</a> to see the code in action</p>