Splitting.js 和 anime.js 等动画库无法在 React JS 上运行
Animation libraries like Splitting.js and anime.js not working on React JS
好的,我已经尝试了 2 个动画库,首先,splitting.js and second anime.js,两者在 vanilla js 上都可以正常工作,但在 react js 上却失败了,知道为什么吗?错误没有意义。请尝试对这两个包进行基本的 npm 安装,并尝试在 react js 项目中使用它们,它们都不起作用。有什么理由吗?以及如何在 React js 中实际使用这些库?我猜它与 React 的 ReactDOM 改变 DOM 元素有关,因此甚至在动画库找到它们之前就删除了所需的元素。
重现我的场景:
请尝试 运行 一个简单的 react js 项目并尝试一个一个地添加这两个动画库
要在您的 React 应用程序中使用 anime.js,您可能需要查看 https://www.npmjs.com/package/react-anime
许多 DOM 操纵库不能开箱即用,因为 React 有自己的做事方式。您可以通过在有效挂钩中执行这些库代码来尝试,而不是在组件声明本身中。
我的想法是使用 react-spring
,它是从头开始构建的,考虑到了 React。另一方面,react-anime 只是 anime.js 的包装器,它将其塑造成 react 的生命周期。
在 React 组件上使用 anime.js 时,您需要确保以 DOM 元素为目标,而不是虚拟 DOM 元素。这是一个例子。它有点旧,但是 code/logic 的 afaik none 已被弃用,并且可以使用 useEffect
挂钩轻松转换为功能组件。
import React from 'react';
import ReactDOM from 'react-dom';
import { TransitionGroup, Transition } from 'react-transition-group';
import anime from 'animejs';
import './style.scss';
class ListItem extends React.Component {
constructor() {
super();
// create li DOM reference
this.liRef = React.createRef();
}
componentDidUpdate(){
this.animeRef = anime({
targets: this.liRef.current,
translateX: () => {
if( this.props.status == 'entering' ) {
return ['-100%', '0%'];
} else if( this.props.status == 'exiting' ) {
return ['0%', '100%'];
}
},
elasticity: () => {
if( this.props.status == 'entering' ) {
return 300;
} else if( this.props.status == 'exiting' ) {
return 0;
}
},
duration: 500
});
}
render() {
return (
<li className="list-item" ref={ this.liRef }>
Hey, I am item number <b>{ this.props.num }</b>
</li>
);
}
}
class App extends React.Component {
constructor() {
super();
this.state = {
data: [1,2,3]
};
}
add() {
this.setState({
...this.state,
data: this.state.data.concat([ this.state.data.length + 1 ])
});
}
remove() {
this.setState({
...this.state,
data: this.state.data.slice(0, -1)
});
}
render() {
return (
<div className="app-container">
<div className="buttons">
<button onClick={ this.add.bind(this) }>Add one</button>
<button onClick={ this.remove.bind(this) }>Remove one</button>
</div>
<TransitionGroup
component="ul"
className="list"
>
{
this.state.data.map( num => (
<Transition
key={ num }
timeout={ 500 }
mountOnEnter
unmountOnExit
>
{
( status ) => {
return <ListItem status={ status } num={ num }/>;
}
}
</Transition>
) )
}
</TransitionGroup>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('app'));
示例来自 this 文章,如果您想了解有关此事的更多信息。
如果你只是想在 codesandbox
中打耳光,这里是 style.scss
好的,我已经尝试了 2 个动画库,首先,splitting.js and second anime.js,两者在 vanilla js 上都可以正常工作,但在 react js 上却失败了,知道为什么吗?错误没有意义。请尝试对这两个包进行基本的 npm 安装,并尝试在 react js 项目中使用它们,它们都不起作用。有什么理由吗?以及如何在 React js 中实际使用这些库?我猜它与 React 的 ReactDOM 改变 DOM 元素有关,因此甚至在动画库找到它们之前就删除了所需的元素。
重现我的场景: 请尝试 运行 一个简单的 react js 项目并尝试一个一个地添加这两个动画库
要在您的 React 应用程序中使用 anime.js,您可能需要查看 https://www.npmjs.com/package/react-anime
许多 DOM 操纵库不能开箱即用,因为 React 有自己的做事方式。您可以通过在有效挂钩中执行这些库代码来尝试,而不是在组件声明本身中。
我的想法是使用 react-spring
,它是从头开始构建的,考虑到了 React。另一方面,react-anime 只是 anime.js 的包装器,它将其塑造成 react 的生命周期。
在 React 组件上使用 anime.js 时,您需要确保以 DOM 元素为目标,而不是虚拟 DOM 元素。这是一个例子。它有点旧,但是 code/logic 的 afaik none 已被弃用,并且可以使用 useEffect
挂钩轻松转换为功能组件。
import React from 'react';
import ReactDOM from 'react-dom';
import { TransitionGroup, Transition } from 'react-transition-group';
import anime from 'animejs';
import './style.scss';
class ListItem extends React.Component {
constructor() {
super();
// create li DOM reference
this.liRef = React.createRef();
}
componentDidUpdate(){
this.animeRef = anime({
targets: this.liRef.current,
translateX: () => {
if( this.props.status == 'entering' ) {
return ['-100%', '0%'];
} else if( this.props.status == 'exiting' ) {
return ['0%', '100%'];
}
},
elasticity: () => {
if( this.props.status == 'entering' ) {
return 300;
} else if( this.props.status == 'exiting' ) {
return 0;
}
},
duration: 500
});
}
render() {
return (
<li className="list-item" ref={ this.liRef }>
Hey, I am item number <b>{ this.props.num }</b>
</li>
);
}
}
class App extends React.Component {
constructor() {
super();
this.state = {
data: [1,2,3]
};
}
add() {
this.setState({
...this.state,
data: this.state.data.concat([ this.state.data.length + 1 ])
});
}
remove() {
this.setState({
...this.state,
data: this.state.data.slice(0, -1)
});
}
render() {
return (
<div className="app-container">
<div className="buttons">
<button onClick={ this.add.bind(this) }>Add one</button>
<button onClick={ this.remove.bind(this) }>Remove one</button>
</div>
<TransitionGroup
component="ul"
className="list"
>
{
this.state.data.map( num => (
<Transition
key={ num }
timeout={ 500 }
mountOnEnter
unmountOnExit
>
{
( status ) => {
return <ListItem status={ status } num={ num }/>;
}
}
</Transition>
) )
}
</TransitionGroup>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('app'));
示例来自 this 文章,如果您想了解有关此事的更多信息。
如果你只是想在 codesandbox
中打耳光,这里是 style.scss