如何在 React 中使用 animejs?
How to use animejs inside React?
我已经从 npm 安装了 animejs 并导入了所需的文件,但是在我的代码中添加 anime(code) 时它无法正常工作并显示错误。
这是我所做的一个小例子:
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;
这是我得到的错误:
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.
正如@Shubham Khatri 指出的那样,已经存在特定于反应的包装器:react-animejs or react-anime 包。如果你不想使用它,你可以使用 anime.js 而无需使用 React hooks 将其直接挂接到 React 中!
在此示例中,我使用 useEffect
挂钩启动动画,并使用 useRef
挂钩存储重新渲染的动画变量,以便它可用于重新启动(或对动画对象执行其他更新)。
您收到错误的原因是 animation
不是 React 元素,因此 React 不知道如何呈现它。相反,将其视为组件中的副作用(因此适合 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" />
设置 ref.current 是不明智的,因为它在技术上是只读的 属性,未来的版本可能会破坏它。
如果您需要访问该值,您应该将 useLayoutEffect 与 useState 结合使用。
这是一个打字稿示例:
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.
注意:您可以毫无问题地将 useLayoutEffect 替换为 useEffect,以防您从中收到错误消息。值得注意的是,如果它在 Next.js
这样的 SSR 上下文中使用
我已经从 npm 安装了 animejs 并导入了所需的文件,但是在我的代码中添加 anime(code) 时它无法正常工作并显示错误。
这是我所做的一个小例子:
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;
这是我得到的错误:
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.
正如@Shubham Khatri 指出的那样,已经存在特定于反应的包装器:react-animejs or react-anime 包。如果你不想使用它,你可以使用 anime.js 而无需使用 React hooks 将其直接挂接到 React 中!
在此示例中,我使用 useEffect
挂钩启动动画,并使用 useRef
挂钩存储重新渲染的动画变量,以便它可用于重新启动(或对动画对象执行其他更新)。
您收到错误的原因是 animation
不是 React 元素,因此 React 不知道如何呈现它。相反,将其视为组件中的副作用(因此适合 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" />
设置 ref.current 是不明智的,因为它在技术上是只读的 属性,未来的版本可能会破坏它。
如果您需要访问该值,您应该将 useLayoutEffect 与 useState 结合使用。 这是一个打字稿示例:
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.
注意:您可以毫无问题地将 useLayoutEffect 替换为 useEffect,以防您从中收到错误消息。值得注意的是,如果它在 Next.js
这样的 SSR 上下文中使用