Skip to content

Child added animation is not working in react StrictMode (or in any other case where autoAnimate() is called twice) #232

Description

@Zachary3234

I found that auto-animate not working in react StrictMode initially, which renders component twice to help find bugs.

So I tested and found that add animation will fail if autoAnimate is called twice (remove animation is fine). Here’s a minimal example:

<ul id="myList">
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ul>
<button onclick="addItem()">Add</button>
<button onclick="removeItem()">Remove</button>
<script>
  const myList = document.getElementById("myList")
  function addItem() {
    const newListItem = document.createElement("li")
    newListItem.appendChild(document.createTextNode(myList.children.length + 1))
    myList.append(newListItem)
  }
  function removeItem() {
    myList.removeChild(myList.children[myList.children.length - 1])
  }
</script>
<script type="module">
  import autoAnimate from 'https://cdn.jsdelivr.net/npm/@formkit/auto-animate'
  autoAnimate(document.getElementById('myList'))
  // autoAnimate(document.getElementById('myList')) // add item is not animated
</script>

I resolved it by checking whether the element already exists in mutationObservers before creating a new MutationObserver. Here's the relevant change:

if (!isDisabledDueToReduceMotion) {
  enabled.add(el)
  if (getComputedStyle(el).position === "static") {
    Object.assign(el.style, { position: "relative" })
  }
  forEach(el, updatePos, poll, (element) => resize?.observe(element))
  if (isPlugin(config)) {
    options.set(el, config as AutoAnimationPlugin)
  } else {
    options.set(el, {
      duration: 250,
      easing: "ease-in-out",
      ...(config as Partial<AutoAnimateOptions>),
    })
  }
  // const mo = new MutationObserver(handleMutations)
  // mo.observe(el, { childList: true })
  // mutationObservers.set(el, mo)
  if (!mutationObservers.has(el)) {
    const mo = new MutationObserver(handleMutations)
    mo.observe(el, { childList: true })
    mutationObservers.set(el, mo)
  }
  parents.add(el)
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions