如何让孩子React组件在一定时间内展示



我有一个名为PopUpBanner的React组件,用于显示消息。例如,在我的登录组件中,我是这样使用它的。如果出现错误,则我将bannerMessage状态设置为有文本,以便横幅显示:

this.setState({
bannerMessage: {
msg: error.message + ". Incorrect email address or password.",
isError: true,
},
});

以下是该组件的使用方法:

<PopUpBanner
message={bannerMessage.msg}
isError={bannerMessage.isError}
></PopUpBanner>

这是PopUpBanner类:

import React, { Component } from "react";
class PopUpBanner extends Component {
constructor(props) {
super(props);
this.state = {
message: this.props.message,
};
}
// TODO : not in use
reset = () => {
this.resetId = setTimeout(
function () {
this.setState({ message: "" });
}.bind(this),
3000
);
};
componentDidMount() {}
componentWillUnmount() {
if (this.timeoutId) {
clearTimeout(this.timeoutId);
console.log("clearing time out");
}
}
render() {
const message = this.props.message;
const isError = this.props.isError;
return (
<div style={message != "" ? { display: "block" } : { display: "none" }}>
<div>
{isError ? (
<div
className="alert alert-danger text-center"
role="alert"
style={{ width: "50%", margin: "auto" }}
>
{message}
</div>
) : (
<div
className="alert alert-primary text-center"
role="alert"
style={{ width: "50%", margin: "auto" }}
>
{message}
</div>
)}
</div>
</div>
);
}
}
export default PopUpBanner;

问题是PopUpBanner一直显示到页面刷新或导航到另一个页面。

所以,如果你看看PopUpBanner类,我试图使用setTimeout,但没能完成

关于如何将PopUpBanner组件转换为计时器,有什么想法吗?

我看到两个选项:

  1. 在父组件中处理它,只在PopUpBanner应该存在的时候渲染它,使用setTimeout触发状态更新,在不渲染PopUpBanner的情况下重新渲染父组件。

  2. PopUpBanner中处理,过期后从render返回null

我更喜欢#1而不是#2。但您现有的代码基本上是在做#2,您只需要调整render来支持它:

render() {
const message = this.props.message;
if (!message) {
return null;
}
// ...show the message...

但正如在评论中所讨论的那样,我不会复制道具来表达这样的观点。因此:

constructor(props) {
super(props);
this.state = {
expiredMessage: null,
};
}

然后过期一条消息:

setupExpiration() {
this.expirationTimer = setTimeout(() => {
this.setState(() => ({expiredMessage: this.props.message}));
}, 1000); // <== Or however long you want it showing
}

你可以从几个生命周期方法中调用:

componentDidMount() {
this.setupExpiration();
}
componentDidUpdate() {
this.setupExpiration();
}

CCD_ 15变为

render() {
const { expiredMessage } = this.state;
const { message } = this.props;
if (expiredMessage === message) {
return null;
}
// ...show the message...

但是,我还是要让家长来控制它,在PopUpBanner不应该显示的时候删除它:

class PopUpBanner extends React.Component {
render() {
const {message} = this.props;
return <div className="banner">{message}</div>;
}
}
class Parent extends React.Component {
state = {
message: null,
};
constructor(props) {
super(props);
this.showMessage = this.showMessage.bind(this);
this.messageTimer = 0;
}
showMessage() {
clearTimeout(this.messageTimer);
this.setState({message: "Hi there, I'm a banner"});
this.messageTimer = setTimeout(() => {
this.setState({message: null});
}, 1000);
}
render() {
const {message} = this.state;
const {showMessage} = this;
return <div className="with-banner">
{message && <PopUpBanner message={message} />}
<div>
<input type="button" value="Show Message" onClick={showMessage} />
</div>
</div>;
}
};
ReactDOM.render(<Parent />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.js"></script>

最新更新