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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions