5

I have installed animejs from npm , and imported the required file, but when adding anime(code) inside my code it does not work prefectly and shows an error .

this is a small example of what I did :

import React from 'react';
import anime from 'animejs';


 const test =()=>{


const animation = anime({
    targets: '.css-selector-demo .el',
    translateX: 250
  });

return(
    <div>
   {
   animation
   }
    </div>
)

}
export default test;

and this is the error that I got :

Error: Objects are not valid as a React child (found: object with keys {update,

begin, loopBegin, changeBegin, change, changeComplete, loopComplete, complete, loop, 
direction, autoplay, timelineOffset, id, children, animatables, animations, 
duration, delay, endDelay, finished, reset, set, tick, seek, pause, play, 
reverse, restart, passThrough, currentTime, progress, paused, began, loopBegan,
 changeBegan, completed, changeCompleted, reversePlayback, reversed, remaining}).
 If you meant to render a collection of children, use an array instead.

azdeviz
  • 597
  • 2
  • 9
  • 20

2 Answers2

23

As @Shubham Khatri pointed out, there are react specific wrappers that already exist: react-animejs or react-anime packages. If you don't want to use that, you can use anime.js without hooking it directly into React by using React hooks!

In this example, I used a useEffect hook to start up the animation, and a useRef hook to store the animation variable across re-renders so it can be used to restart (or perform other updates on the animation object).

The reason you were getting an error is because animation isn't a react element, so React doesn't know how to render it. Instead, think of it as a side effect within your component (hence suitable to useEffect).

function App() {
  const animationRef = React.useRef(null);
  React.useEffect(() => {
    animationRef.current = anime({
      targets: ".el",
      translateX: 250,
      delay: function(el, i) {
        return i * 100;
      },
      loop: true,
      direction: "alternate",
      easing: "easeInOutSine"
    });
  }, []);
  return (
    <div className="App">
      <button onClick={()=>animationRef.current.restart()}>Restart</button>
      <div className="el" />
    </div>
  );
}

ReactDOM.render(<App/>,document.querySelector('#root'));
.el {
  height: 16px;
  width: 16px;
  background-color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.0/anime.min.js" integrity="sha256-hBMojZuWKocCflyaG8T19KBq9OlTlK39CTxb8AUWKhY=" crossorigin="anonymous"></script>

<div id="root" />
Zachary Haber
  • 10,376
  • 1
  • 17
  • 31
  • 1
    None of the libraries on npm actually work for >90% of Anime.js use cases, which is tragic, but understandable since Anime.js is insanely powerful. But I've rarely gotten them to work even for simple fades and transforms. You'll probably just waste half a week like we did if you try to use them. – Slbox Oct 08 '20 at 20:29
  • 1
    Yeah. Libraries are no good. This solution worked perfectly. Thanks Zachary – Ronn Wilder Feb 23 '21 at 09:21
  • Where's this .restart() coming from? – rom Feb 10 '22 at 18:52
  • 1
    It's a reference to the Anime.js's animation object. It's set via animationRef.current = anime({...}). For reference, here's the animeJs documentation: https://animejs.com/documentation/#restartAnim – Zachary Haber Feb 10 '22 at 20:16
3

Setting ref.current is unwise as it's technically a readonly property and future releases could break it.

If you need access to the value you should combine a useEffect with a useState. Here's a typescript example:

import anime from "animejs";
import React, { useEffect, useState } from "react";

const [animationRef, setAnimationRef] = useState<ReturnType<typeof anime> | undefined>();

useEffect(() => {
    setAnimationRef(
        anime({
            // init props
        }),
    );
}, []); // Only run once.
TheDeafOne
  • 93
  • 10
Prometheus
  • 61
  • 7