代码之家  ›  专栏  ›  技术社区  ›  Taylor Austin

如何在react中设置func comp的动画?

  •  0
  • Taylor Austin  · 技术社区  · 8 年前

    通常,在基于类的comp中,只需使用componentdidmount和settimeout来动态地设置状态,并将一个类添加到主div中并设置动画。我试图做同样的事情,只是把类传递给func comp,但它不起作用。我现在想坚持使用纯css。

    我在react中有一个功能组件,如下所示:

    import React from 'react';
    
    export default (props.class) => {
     return (
      <div className={`animate ${props.class}`}>
        Hello World
      </div>
     )
    }
    

    Main App:
    

    import React, { Component} from 'react';
    import FuncComp from './FuncComp';
    
    export default class App extends Component {
     constructor(props){
      super(props) 
    
      this.state = { class: '' }
     }
    
     componentDidMount() {
      setTimeout(() => { this.setState({class: 'animateAction'}), 0)
     }
    
     render(){
      return (
      <div>
       <FuncComp class={this.state.class} />
      </div>
     )
    }
    }
    

    外部CSS:

    .animate {
     transform: scaleY(0);
     transition: transform 1s ease;
    }
    .animateAction {
     transform: scaleY(1);
    }
    
    1 回复  |  直到 8 年前
        1
  •  0
  •   Taylor Austin    8 年前

    我想这会是一个有点混乱的答案,但我找到了一种加载动画和延迟组件卸载的方法。

    这是针对功能组件的,因为其中一半可以在comp本身的基于类的comp中完成。

    编辑:这对基于类的comp同样有效。

    注意:base是基类,action是要为动画执行的操作。

    import React, { Component } from 'react'
    
    export default Comp => {
      return class extends React.Component {
        constructor(props) {
          super(props)
          this.state = {
            shouldRender: this.props.isMounted,
            didMount: false
          }
        }
    
        componentWillReceiveProps(nextProps) {
          if (this.props.isMounted && !nextProps.isMounted) {
            setTimeout(() => {
              this.setState({ shouldRender: false })
            }, this.props.delayTime)
            this.setState({ didMount: false })
          } else if (!this.props.isMounted && nextProps.isMounted) {
            setTimeout(() => {
              this.setState({ didMount: true })
            }, 0)
            this.setState({ shouldRender: true })
          }
        }
    
        render() {
          const { didMount } = this.state
          const { base, action, isMounted } = this.props
          return this.state.shouldRender ? (
            <div className={`${base} ${didMount && isMounted ? action : ''}`}>
              <Comp {...this.props} />
            </div>
          ) : null
        }
      }
    }
    

    好了,现在使用这个新的hoc,我们可以这样包装我们的func comp。

    import React from 'react'
    import AnimateHOC from './AnimateHOC'
    
    const myFuncComp = (props.class) => {
     return (
      <h1>
        Hello World
      </h1>
     )
    }
    
    const AnimateComp = AnimateHOC(myFuncComp);
    

    在基于类的comp中使用如下:

    render() {
     return (
      <div>
       <AnimateComp
        delayTime={500}
        isMounted={this.state.isMounted}
        base={'animate'}
        action={'animateAction'}
       />
       <button onClick={this.setState({ isMounted: !this.state.isMounted }) }>Toggle</button>
      </div>
     )
    }
    

    最后是外部css:

     .animate {
        transform: scaleY(0);
        transform-origin: top;
        transition: all 0.5s linear;
      }
    
      .animateAction {
        transform: scaleY(1);
      }
    

    临界的 :将延迟时间与动画时间匹配,否则将无法正常工作。延迟时间以ms为单位,因此500=0.5s