Search code examples
reactjsreact-nativetimer

Proper way to use clearTimeout and setTimeout?


I'm getting a memory leak error whenever I navigate away from the screen when the setTimeout function is running. I know I'm supposed to clear the timer but it's not working for me. I'm missing something somewhere...

Here's my code. I removed a lot of the content that was irrelevant to this issue so pardon me if some syntax looks wrong or if there's a without a closing tag.

Thanks!

export default class EditContent extends Component {
    timer;

    constructor(props) {
        super(props);

        this.state = {           
            isLoading: false,
            buttonMessage: 'Save Changes'
        }

    }

    componentWillMount(){
        this.timer
    }

    componentWillUnmount() {
        clearTimeout(this.timer)
    }


    handleLoading(bool) {
        this.setState({
            loading: bool,
            buttonMessage: !bool && 'Changes Saved!'
        })
        this.timer = setTimeout(() => {
            this.setState({ buttonMessage: 'Save Changes' })
        }, 5000);

    }



    handleBack() {
        clearTimeout(this.timer)
        this.props.navigation.goBack(null)
    }

    handleSaveChanges() {
        const { goBack } = this.props.navigation;
        this.handleLoading(true)

        this.props.updateDeliveryPickup()
            .then((resp) => {
                this.handleLoading(false)
                console.log('resp', resp)
            })
    }

    render() {
        const { pickup } = this.props


        return (

            <View style={styles.editWrapper}>


                <View style={styles.userStoreHeader}>
                    <Text>My Account</Text>
                </View>

                <Subheader onPressBack={() => this.handleBack()} />

                <View style={styles.summaryContainer}>

                    <SettingsButton
                        onPress={() => this.handleSaveChanges()}
                        buttonMessage={buttonMessage}
                    />

                </View>
            </View>
        )
    }
}

Solution

  • First of all onPress={() => this.handleSaveChanges()} is a bad practise, it will create a new function for each render of the component, you should directly write onPress={this.handleSaveChanges}, the same could be applied to onPressBack : <Subheader onPressBack={this.handleBack} />

    In handleLoading you probably need to call clearTimeout(this.timer) before calling this.timer = setTimeout...