How to use animejs inside React?

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.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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" />

Method 2

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 useLayoutEffect with a useState.
Here’s a typescript example:

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

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

useLayoutEffect(() => {
    setAnimationRef(
        anime({
            // init props
        }),
    );
}, []); // Only run once.

Note: You can likely replace useLayoutEffect with useEffect without issue, in case you’re getting error messages from it. Notably if it’s being used in an SSR context like Next.js


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x