[英]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 结合使用来执行淡出行为。
用法:
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
钩子结合了所有这三个componentDidMount
、componentDidUpdate
和componentWillUnmount
你的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>}
/>
</>
)
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.