Skip to content

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

@Zachary3234

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)
}

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