'React setState componentDidUpdate React limits the number of .. when trying to update the state based on updated state

i have react program that need the data from other components. When the parent components send path data, an array will get all of the files name inside folder, and also i need to count the data length to make sure file list will not empty. Several data need to stored to state and will re-used for the next process. Below is the programs.

  constructor() {
    super()

    this.state = {
      fulldir: null,
      listfileArray: [],
      isDataExist: true
    }
  }
  componentDidUpdate()
  {
    let path = this.props.retrievefilespath
    let dirLocation = Utils.fulldirFunc(path)
    let rdir = fs.readdirSync(dirLocation)
    let countList = 0
    rdir.forEach((filename) => {
        this.state.listfileArray.push({
                id: countList,
                name: filename,
                selected: false
            })
        countList++
    })
    if(countList > 0)
      this.setState({
        isDataExist: true
      })
  }

But this program returns error

Error Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

Previously i used vuejs and use data to handle the data flow

data () {
        return {
            listfile: [],
            isActive: false,
            isDataExist: false,
            arrayIdx: []
        }
    },
    watch: {
        lfdirHandler: function () {
            //reset data from previous action
            Object.assign(this.$data, getInitialData())

            //electron filesystem
            const fs = require('fs')
            if(this.lfdirHandler.length > 0)
            {
                let dirLocation = Utils.fulldirFunc(this.lfdirHandler)
                let rdir = fs.readdirSync(dirLocation)
                var countList = 0
                rdir.forEach((filename) => {
                    this.listfile.push({
                            id: countList,
                            name: filename,
                            selected: false
                        })
                    countList++
                })
                if(countList > 0)
                    this.isDataExist = true
            }
        },

So, what's the best solution to this problem? I mean, how to handle the data flow like what i've done with vue? is it right to use react state? Thanks.



Solution 1:[1]

i'm confuse with the documentation written here

componentDidUpdate(prevProps) {
  // Typical usage (don't forget to compare props):
  if (this.props.userID !== prevProps.userID) {
    this.fetchData(this.props.userID);
  }
}

after several test, i think the documentation should be written like following code:

componentDidUpdate(props) {
  // Typical usage (don't forget to compare props):
  // props.userID as previous data
  if (this.props.userID !== props.userID) {
    this.fetchData(this.props.userID);
  }
}

this prevProps is confusing me.
So, the solution based on the documentation is, you need to compare, whether data inside props.userID is equal to this.props.userID.

Notes:

  • this.props.userID bring new data
  • props.userID bring old data

props.userID is saving your data from your previous action. So, if previously you setstate userID with foo. The program will save it to props.userID.

componentDidUpdate(props) {
// this.props.userID  -> foo
// props.userID       -> foo
  if (this.props.userID !== props.userID) {
      // false
      // nothing will run inside here
  }
}
componentDidUpdate(props) {
// this.props.userID  -> foo
// props.userID       -> bar
  if (this.props.userID !== props.userID) {
      // true
      // do something
  }
}

my program here:

componentDidUpdate()
{
   let path = this.props.retrievefilespath
   //....
}

is infinitely compare this.props.retrievefilespath with nothing. That's why the program return error.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 dhanyn10