繁体   English   中英

在设定的时间后从 DOM 中删除元素

[英]Removing element from DOM after set amount of time

我试图找出在事件触发后从 DOM 中删除元素的 React 方法。

我试图在onClick={this.props.handleCopyFact}被触发时发出警报( copySuccess ),然后在 5 秒后淡出该警报。 每个组件的状态都在父组件中设置。

这是我的组件的代码:

module.exports = React.createClass({

render: function() {

var copy = null;
if (!this.props.copying && !this.props.editting) {
  copy = (
    <div className="copy-fact-container" onClick={this.props.handleCopyFact}>
      <i className="icon-copy"></i>
      <span>Copy</span>
    </div>
    );

}

var copySuccess = null;
if (this.props.copySuccess) {
  copySuccess = (
    <div className="copy-success">
      <div><i className="icon icon-clipboard"></i></div>
      <p className="heading">Copied to Clipboard</p>
    </div>
    );
}

return (
  <div className="row-body"
    onMouseEnter={this.props.toggleCopyFact}
    onMouseLeave={this.props.toggleCopyFact}>
    <MDEditor editting={this.props.editting}
      content={this.props.content}
      changeContent={this.props.changeContent}/>
  {copy}
  {copySuccess}
  </div>
);
}
});

一种方法是创建一个 Expire 组件,该组件将在延迟后隐藏其子项。 您可以将它与 CSSTransitionGroup 结合使用来执行淡出行为。

jsbin

用法:

render: function(){
    return <Expire delay={5000}>This is an alert</Expire>
}

组件:

var Expire = React.createClass({
  getDefaultProps: function() {
    return {delay: 1000};
  },
  getInitialState: function(){
    return {visible: true};
  },
  componentWillReceiveProps: function(nextProps) {
    // reset the timer if children are changed
    if (nextProps.children !== this.props.children) {
      this.setTimer();
      this.setState({visible: true});
    }
  },
  componentDidMount: function() {
      this.setTimer();
  },
  setTimer: function() {
    // clear any existing timer
    this._timer != null ? clearTimeout(this._timer) : null;

    // hide after `delay` milliseconds
    this._timer = setTimeout(function(){
      this.setState({visible: false});
      this._timer = null;
    }.bind(this), this.props.delay);
  },
  componentWillUnmount: function() {
    clearTimeout(this._timer);
  },
  render: function() {
    return this.state.visible 
           ? <div>{this.props.children}</div>
           : <span />;
  }
});

更新了 @FakeRainBrigand 的答案以支持更现代的 React 语法,该语法使用类代替已弃用的React.createComponent方法。

class Expire extends React.Component {
  constructor(props) {
    super(props);
    this.state = {visible:true}
  }

  componentWillReceiveProps(nextProps) {
    // reset the timer if children are changed
    if (nextProps.children !== this.props.children) {
      this.setTimer();
      this.setState({visible: true});
    }
  }

  componentDidMount() {
    this.setTimer();
  }

  setTimer() {
    // clear any existing timer
    if (this._timer != null) {
      clearTimeout(this._timer)
    }

    // hide after `delay` milliseconds
    this._timer = setTimeout(function(){
      this.setState({visible: false});
      this._timer = null;
    }.bind(this), this.props.delay);
  }

  componentWillUnmount() {
    clearTimeout(this._timer);
  }

  render() {
    return this.state.visible
      ? <div>{this.props.children}</div>
      : <span />;
  }
}

进一步简化了使用Hooks 的方式

来自React Hooks文档,

useEffect钩子结合了所有这三个componentDidMountcomponentDidUpdatecomponentWillUnmount

你的Expire组件应该是

import React, { useEffect, useState } from "react";

const Expire = props => {
  const [visible, setVisible] = useState(true);

  useEffect(() => {
    setTimeout(() => {
      setVisible(false);
    }, props.delay);
  }, [props.delay]);

  return visible ? <div>{props.children}</div> : <div />;
};

export default Expire;

现在,在Expire组件中传递delay道具。

<Expire delay="5000">Hooks are awesome!</Expire>

我使用Codesandbox创建了一个工作示例

更新了 @pyRabbit 以使用更新的 React 钩子和 prop 字段来切换children组件的可见性:

const DelayedToggle = ({ children, delay, show }) => {
  let timer = null;

  // First, set the internal `visible` state to negate 
  // the provided `show` prop
  const [visible, setVisible] = useState(!show);

  // Call `setTimer` every time `show` changes, which is
  // controlled by the parent.
  useEffect(() => {
    setTimer();
  }, [show]);

  function setTimer() {
    // clear any existing timer
    if (timer != null) {
      clearTimeout(timer)
    }

    // hide after `delay` milliseconds
    timer = setTimeout(() => {
      setVisible(!visible);
      timer = null;
    }, delay);
  }

  // Here use a `Fade` component from Material UI library
  // to create a fade-in and -out effect.
  return visible 
    ?
    <Fade in={show} timeout={{
      enter: delay + 50,
      exit: delay - 50,
    }}
    >
      {children}
    </Fade>
    : <span />;
};

const Parent = () => {
  const [show, setShow] = useState(false);
  return (
    <>
      <button onClick={() => setShow(!show)}>toggle</button>
      <DelayedToggle 
        delay={300} 
        show={show}
        children={<div><h1>Hello</h1></div>}
      />
    </>
  )
};

编辑 Peace-galileo-hvqb5

暂无
暂无

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

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