title: how to animate state transitions in Blazor when rendering a list of object with their own lifecycle?
body: <p>I know that there is a post closely related to my question (<a href="https://stackoverflow.com/questions/56219984/how-to-animate-state-transitions-in-blazor">How to animate state transitions in Blazor?</a>).
  However, my problem is the following : Consider a list of toasts for instance. I want to display 5 toasts, they can be removed by clicking on them, or they remove themselves when their timers is out.</p>
  <p><em>Code simplified as example.</em></p>
  <p><strong>Component Toasts</strong></p>
  <pre><code>@inject ToastService ToastService
  
  &lt;div class=&quot;toasts&quot;&gt;
      @foreach (ToastData data in ToastService.List)
      {
           &lt;Toast Data=&quot;data&quot; /&gt;
      }
  &lt;/div&gt;
  
  @code {
      protected override async Task OnInitializedAsync()
      {
          ToastService.OnListChange += RefreshList;
      }
  
      public void RefreshList()
      {
          StateHasChanged();
      }
  }
  </code></pre>
  <p><strong>ToastService</strong></p>
  <pre><code>public class ToastService
  {
      private List&lt;ToastData &gt; _list;
      public List&lt;ToastData &gt; List
      {
          get
          {
              var list = _list.Take(5).ToList();
              foreach (ToastData data in list)
              {
                  data.StartCountDown();
              }
              return list;
          }
      }
      public event Action OnListChange;
  
      public ToastService()
      {
          _List = new List&lt;ToastData &gt;();
      }
  
      public async Task CreateToast(ToastData data)
      {
          _list.Add(data);
          OnListChange?.Invoke();
      }
  
      public async Task RemoveToast(ToastData data)
      {
          _list.Remove(data);
          OnListChange?.Invoke();
      }
  }
  </code></pre>
  <p><strong>ToastData</strong></p>
  <pre><code>public class ToastData
  {
      private ToastService _toastService;
      private bool _isCountdownStarted;
      private System.Timers.Timer _countdown;
  
      public ToastData(ToastService toastService)
      {
          _toastService= toastService;
      }
  
      public void StartCountDown()
      {
          if (_isCountdownStarted)
              return;
  
          _countdown = new System.Timers.Timer(5000);
          _countdown.AutoReset = false;
          _countdown.Start();
          _countdown.Elapsed += RemoveNotification;
          _isCountdownStarted = true;
      }
  
      public void RemoveNotification()
      {
          _countdown.Close();
          _toastService.RemoveNotification(this);
      }
  
      private void RemoveNotification(object source, ElapsedEventArgs args)
      {
          RemoveNotification();
      }
  }
  </code></pre>
  <p><strong>Component Toast</strong></p>
  <pre><code>&lt;div @onclick=&quot;Clicked&quot; class=&quot;toast&quot;&gt;
      Some message on a toast
  &lt;/div&gt;
  
  @code {
      [Parameter] public ToastData Data { get; set; }
  
      public void Clicked()
      {
          Data.RemoveNotification();
      }
  }
  
  </code></pre>
  <p>The above example work fine, cause there's no animation yet.
  But now, I want to add an animation of the Toast component. So I modify the ToastData to first call a Hide method, this method will notify the Toast component who will add a CSS class that will animate the removal.
  This works fine, until this happen :</p>
  <ul>
  <li>Toast component 1 start to animate the removal</li>
  <li>Toast component 2 start to animate the removal</li>
  <li>Toast 1 is removed, the list is refreshed</li>
  <li>Toast 2 is now Toast 1, the animation is gone, and suddenly it disappear</li>
  <li>Worst even, a Toast 3 would become Toast 2 and will animate even if not intended to be removed yet.</li>
  </ul>
  <p>I understand that Blazor choose to reuse HTML, that's why in the Toasts component, all Toast component will always be the same. That's why I put the logic in the ToastData.
  I'm guessing I'm missing something...</p>
  <p>Any help or insight appreciated!</p>