sdsd
sdsd

Reputation: 517

UseEffect clean up function don't remove my interval

I have App and Test component.

App

import "./App.css";
import { React, useState, useEffect} from 'react';
import Test from './Test';

function App() {
  const [load, setLoad] = useState(true);
  useEffect(() => {
    console.log('useEffect called');
  })

  return (
    <div>
       {load ? <Test></Test> : null}
       <button onClick={() => setLoad(!load)}>Toggle</button>
    </div>
  );
}

export default App;

Test

import React from 'react'

class Test extends React.Component {
    counter = 0;
    interval;
    componentDidMount() {
        console.log('componentDidMount')

        this.interval = setInterval(() => {
            console.log(this.counter++);
        },1000)
    }

    componentWillUnmount() {
        clearInterval(this.interval);
    }
    render() {
        return (
            <div>
                <h1>test</h1>
            </div>
        )
    }
}

export default Test

when the Test componenet is detroyed i want to clean the interval

If i use class component

import React from 'react'

class Test extends React.Component {
    counter = 0;
    interval;
    componentDidMount() {
        console.log('componentDidMount')

        this.interval = setInterval(() => {
            console.log(this.counter++);
        },1000)
    }

    componentWillUnmount() {
        clearInterval(this.interval);
    }
    render() {
        return (
            <div>
                <h1>test</h1>
            </div>
        )
    }
}

export default Test

this will work when i click for example on the Toggle component the interval is cleared.

But if i use functional component

import React, { useEffect } from 'react'

function Test() {
    let counter = 0;
    useEffect(() => {
        let interval = setInterval(() => {
            counter++;
            console.log(counter);
            return () => {
                console.log('interval', interval)
                clearInterval(interval);
            }
        },1000)
    })
    return (
        <div>
            <h1>Test</h1>
        </div>
    )
}

export default Test

THEN IT IS NOT WORKING.When test component is detroyed i still get interval printed in console

How can i make the clean up here ?

Upvotes: 0

Views: 85

Answers (2)

GokulnathP
GokulnathP

Reputation: 712

Return should be added for useEffect, which will used when component is unmount

import React, { useEffect } from 'react'

function Test() {
    let counter = 0;
    useEffect(() => {
        let interval = setInterval(() => {
            counter++;
            console.log(counter);
        },1000)
        return () => {
            console.log('interval', interval)
            clearInterval(interval);
        }
    })
    return (
        <div>
            <h1>Test</h1>
        </div>
    )
}

export default Test

Upvotes: 0

DoneDeal0
DoneDeal0

Reputation: 6257

You need to add the return below the interval. All useEffects cleanup occur as such:

useEffect((){
 //do stuff
 return ()=> //clean stuff
 }, [])

Also, don't forget the dependency array in the end of your useEffect.

Upvotes: 1

Related Questions