I'm attempting to write a HOC that changes its state attribute visible
to false
after some time.
Here is what I've got so far:
const withExpire = (WrappedComponent) =>
class extends Component {
constructor(props) {
super(props);
this.state = {
visible: props.visible,
};
}
render() {
const expire_in = this.props.expire_in || 3000;
if (this.state.visible) {
setTimeout(() => {
this.setState({ visible: false });
}, 1000);
}
return <WrappedComponent visible={this.state.visible} {...this.props} />;
}
}
I've checked that code inside if (this.state.visible)
runs, but it doesn't change my visible
attribute.
Can someone explain me what I'm missing?
EDIT
SOLUTION:
const withExpire = (WrappedComponent) =>
class extends Component {
constructor(props) {
super(props);
this.state = {
visible: props.visible,
};
this.timeoutID = null;
}
componentWillMount () {
const expire_in = this.props.expire_in || 3000;
if (this.state.visible) {
this.timeoutID = setTimeout(() => {
this.setState({ visible: false });
}, expire_in);
}
}
componentWillUnmount () {
if (this.timeoutID) {
window.clearTimeout(this.timeoutID);
}
}
render () {
return <WrappedComponent {...this.props} visible={this.state.visible} />;
}
}
You actually implemented the perfect example against HOC usage. You can't be sure about what's coming in from the outside as props.
In this example the external visible
property through {...this.props}
overrides the visbile={this.state.visible}
property.
A quick fix (by swapping the order of property definitions):
...
return <WrappedComponent {...this.props} visible={this.state.visible} />;
...
Also, don't forget to properly handle the Timer. You should store any timers and if still active cancel them in componentWillUnmount
. Otherwise a still running timer in an unmounted component might cause errors thrown around.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.