Search code examples
reactjsreact-nativereact-reduxreact-hooksuse-effect

Why useEffect makes infinitive loop if pass the second param as array and inside put empty object


I have object with filter params for API and this object I pass to useEffect.

    let dataForFilter = typeof defaultFormData[someKey] !== 'undefined'
    ? defaultFormData[someKey]
    : {};

    for (let key in props.route.params) {
        if (props.route.params.hasOwnProperty(key)) {
            dataForFilter[key] = props.route.params[key];
        }
    }

    useEffect(() => {
        async function fetchData() {
            const body = {
               ...dataForFilter,
            };
            loadData(url, body);
        }
        fetchData();
    }, [dataForFilter]);

By default the object is empty but this makes infinite loop if I pass empty object in array as second parameter. I don't understand why? Please could somebody explain me why and how this solve.


Solution

  • Every time the function runs, it creates a new empty object here:

    let dataForFilter = typeof defaultFormData[someKey] !== 'undefined'
        ? defaultFormData[someKey]
        : {};
    

    So the dependency array's values change every render, if defaultFormData[someKey] doesn't exist. The empty object isn't equal to itself.

    console.log([{}] === [{}]);
    console.log({} === {});

    Create the object outside the function instead, so that its reference is stable.

    const emptyObj = {};
    const MyComponent = ({ defaultFormData }) => {
      // ...
      let dataForFilter = typeof defaultFormData[someKey] !== 'undefined'
        ? defaultFormData[someKey]
        : emptyObj;