Removing items from state by timer

There is a local state (hook), it has an array of four elements. There is a button on the screen to add a new element to this array. When a component is loaded, in useEffect called method that removes the first element from the state every 5 seconds. If you do not touch the button that adds a new element to the state, then everything works great. But if you start adding elements, the deletion works according to the previous state, only then the state with the new element is displayed. Tell me how to fix it so that everything works stably. I understand what needs to be sought in the direction of the life cycle, a conflict of states occurs, but I can not find a solution.

const Component = () => {

    const [arr, setArr] = useState(['one', 'two', 'three', 'four']);

    React.useEffect(() => {
        console.log("render");
        setTimeout(deleteElementFromArr, 5000)
    });

    const addNewElementToArr = () => {
        let temp = arr.slice();
        temp.push('newElement');
        setArr(temp);
    };

    const deleteElementFromArr = () => {
        if (arr.length > 0) {
            console.log(arr);
            let temp = arr.slice();
            temp.splice(0, 1);
            setArr(temp)

        }
    };

    return (<div>
        <div>
            <Button onClick={addNewElementToArr}>add</Button>
        </div>
        <div style={{margiTop: '10px'}}>
            {arr.map(a => `${a} `)}
        </div>
    </div>)
};

https://codepen.io/slava4ka/pen/WNNvrPV

Upvotes: 0

Views: 1285

Answers (1)

cOkO
cOkO

Reputation: 316

In your useEffect hook, when the effect is finished, clear the timeout. When the state is changed, it will trigger again with the new value of the state.

React.useEffect(() => {
    console.log("render");
    const timer = setTimeout(deleteElementFromArr, 5000);
    return () => clearTimeout(timer);
});

Upvotes: 2

Related Questions