Home > Blockchain >  React UseEffect render infinite loop
React UseEffect render infinite loop

Time:08-30

I seem to have an infinite loop in my code but I can't seem to see where, I usually see this if I am setting the state of something that is a dependency of useEffect but here the two variables (values / items) are completely seperate.

App.js

import React from 'react';
import './style.css';
import MyComponent from './MyComponent.js';

export default function App() {
  return (
    <div>
      <MyComponent />
    </div>
  );
}

MyComponent.js

import React, { useEffect, useState } from 'react';

const MyComponent = ({ values = [] }) => {

  console.log('MyComponent Reloaded');
  const [items, setItems] = useState();

  useEffect(() => {
    const loadItems = () => {
      //setItems([]);   //why does this cause infinite render loop?
    };

    loadItems();
  }, [values]);

  return <></>;
};

export default MyComponent;

Why does this cause a render loop?

I have an example build Here (Uncomment the commented line to begin render loop)

CodePudding user response:

You need to introduce the default values of the props the right way:

import React, { useEffect, useState } from 'react';

const MyComponent = ({ values }) => {
  console.log('MyComponent Reloaded');
  const [items, setItems] = useState();

  useEffect(() => {
    console.log(values)
    const loadItems = () => {
      setItems([]);
    };

    loadItems();
  }, [values]);

  return <></>;
};

MyComponent.defaultProps = {
  values: []
}

export default MyComponent;

CodePudding user response:

There are two possible bugs in the code:

  • According to your code, values variable is created every time, when checked with the previous values variable it is not same. So it causes infinite loop.

    • To fix this use default props.

      const MyComponent = ({ values }) => {
       ...
      
      MyComponent.defaultProps = {
        values: []
      }
      
  • As in your question,this line causes you the infinite loop

       //setItems([]);
    
    • To overcome this

      Add items dependency along with values, so that both values are watched before re-rendering.

      useEffect(() => {
      console.log(values)
      const loadItems = () => {
        setItems([]);
      };
      
      loadItems();
      }, [values,items]);
      
  • Related