-2

I've created a basic React component as a sandbox. I added a doSomething() function to the component which simply displays an alert on useEffect(). However, the alert is getting called in an infinite loop. So obviously, there's something wrong with the design. Any idea what the design issue is with this component which is causing the infinite loop? What steps would you recommend to redesign this component in order to fix that issue?

import {Repository} from '../data/Repository';
import { useEffect , useState} from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { decrement, increment } from '../features/counter/counterSlice';
import { setIsValid } from '../features/userManagement/userManagementSlice';

export const UserManagement = () => {
    const [userTestData, setUserTestData] = useState([]);
    const [userCount, setUserCount] = useState(0);
    const count = useSelector((state) => state.counter.value)
    const isValid2 = useSelector((state) => state.userManagement.isValid2)
    const dispatch = useDispatch()

    const doSomething = () => {
        alert('about to do something');
    }

    useEffect(() => {
        doSomething();
        setUserTestData(Repository.getUserTestData());
    })

    useEffect(() => {
        setUserCount(userTestData.length);
    }, [userTestData])

    //debugger;

    return(
        <>

            <div>
                {
                    userTestData.map((x) => {
                        return <div key={x.Id}>{x.FirstName}</div>
                    })
                }
            </div>
            <div>there are {userCount} users</div>

            <div>

            {/* PARENT INPUT VALIDATION */}
            <div style={{height:100}}>
                <button onClick={() => dispatch(setIsValid())}>
                    TOGGLE VALIDATION
                </button>
                {isValid2 ? 'true' : 'false'}
            </div>

            {/* COUNTER */}
            <div>
                <button
                aria-label="Increment value"
                onClick={() => dispatch(increment())}
                >
                Increment
                </button>
                <span>{count}</span>
                <button
                aria-label="Decrement value"
                onClick={() => dispatch(decrement())}
                >
                Decrement
                </button>
            </div>
            </div>
        </>
    )
}
  • Does this answer your question? [Infinite loop in useEffect](https://stackoverflow.com/questions/53070970/infinite-loop-in-useeffect) – Youssouf Oumar Jun 24 '22 at 18:35

1 Answers1

0

The issue here.

useEffect(() => {
    doSomething();
    setUserTestData(Repository.getUserTestData());
})

You didn't add array of dependences to useEffect, so it's callback will be excuted on each render of the component, and as you set a State by setUserTestData, so the component will still re-render in infinite loop.

To fix.

useEffect(() => {
    doSomething();
    setUserTestData(Repository.getUserTestData());
}, [])
Mina
  • 14,386
  • 3
  • 13
  • 26