简体   繁体   中英

How to write “Expire in” HOC?

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.

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