简体   繁体   English

React - 动画结束后如何使元素消失?

[英]React - How do I make an element disappear after animation ends?

Background 背景

演示

I am trying to make an element disappear after the animation ends (I am using animate.css to create the animations). 我试图让一个元素在动画结束后消失(我使用animate.css来创建动画)。

The above 'copied' text uses animated fadeOut upon clicking the 'Copy to Journal Link'. 上面的“复制”文本在单击“复制到日记链接”时使用animated fadeOut Additionally, the above demo shows that it takes two clicks on the link to toggle the span containing the text 'copied' from displayed to not displayed. 此外,上面的演示显示,只需点击两次链接即可将包含“已复制”文本的范围切换为不显示。

According to the animate.css docs, one can also detect when an animation ends using: 根据animate.css文档, 还可以使用以下方法检测动画的结束时间

const element =  document.querySelector('.my-element')
element.classList.add('animated', 'bounceOutLeft')

element.addEventListener('animationend', function() { doSomething() })

My Problem 我的问题

However, within the componentDidMount() tooltip is null when attempting to integrate what animate.css docs suggest. 但是,在尝试集成animate.css文档建议的内容时, componentDidMount() tooltipnull

What am I doing wrong? 我究竟做错了什么? Is there a better way to handle this behavior? 有没有更好的方法来处理这种行为?

ClipboardBtn.js ClipboardBtn.js

import React, { Component } from 'react'

import CopyToClipboard from 'react-copy-to-clipboard'

class ClipboardBtn extends Component {
    constructor(props) {
        super(props)

        this.state = {
            copied: false,
            isShown: true,
        }
    }

    componentDidMount() {
        const tooltip = document.querySelector('#clipboard-tooltip')
        tooltip.addEventListener('animationend', this.handleAnimationEnd)
    }

    handleAnimationEnd() {
        this.setState({
            isShown: false,
        })
    }

    render() {
        const { isShown, copied } = this.state
        const { title, value } = this.props

        return (
            <span>
                <CopyToClipboard onCopy={() => this.setState({ copied: !copied })} text={value}>
                    <span className="clipboard-btn">{title}</span>
                </CopyToClipboard>
                {this.state.copied ? (
                    <span
                        id="clipboard-tooltip"
                        className="animated fadeOut"
                        style={{
                            display: isShown ? 'inline' : 'none',
                            marginLeft: 15,
                            color: '#e0dbda',
                        }}
                    >
                        Copied!
                    </span>
                ) : null}
            </span>
        )
    }
}
export default ClipboardBtn

componentDidMount gets called only once during the inital mount. 在初始安装期间, componentDidMount仅被调用一次。 I can see that in the inital component state, copied is false , hence #clipboard-tooltip never gets rendered. 我可以看到,在初始组件状态中, copiedfalse ,因此#clipboard-tooltip永远不会被渲染。 That is why tooltip is null. 这就是工具提示为空的原因。

Instead try this : 而是试试这个:

componentDidUpdate(prevProps, prevState) {
  if(this.state.copied === true && prevState.copied === false) {
    const tooltip = document.querySelector('#clipboard-tooltip')
    tooltip.addEventListener('animationend', this.handleAnimationEnd)
  }
  if(this.state.copied === false && prevState.copied === true) {
    const tooltip = document.querySelector('#clipboard-tooltip')
    tooltip.removeEventListener('animationend', this.handleAnimationEnd)
  }
}

componentDidUpdate gets called for every prop/state change and hence as soon as copied is set to true, the event handler is set inside componentDidUpdate . 为每个prop / state更改调用componentDidUpdate ,因此一旦copied设置为true,就会在componentDidUpdate设置事件处理程序。 I have added a condition based on your requirement, so that it doesn't get executed everytime. 我根据您的要求添加了一个条件,因此不会每次都执行。 Feel free to tweak it as needed. 随意根据需要调整它。

Using query selectors in React is a big NO. 在React中使用查询选择器是一个很大的NO。 You should NEVER do it. 你永远不应该这样做。 (not that that's the problem in this case) (不是说这个问题就是这个问题)

But even though it's not the problem, it will fix your problem: 但即使这不是问题,它也会解决您的问题:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    return <div ref={this.myRef} />;
  }
}

https://reactjs.org/docs/refs-and-the-dom.html https://reactjs.org/docs/refs-and-the-dom.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM