0

I am trying to send data Action from my dashboard page this.props.dataActions.addChild(this.props.user.children.data[0]).

But I have a problem with a loop. I don't know what to do in this case. Please check my code below:

I tried to add loading to componentDidUpdate but it's not helped.

componentDidUpdate() {
    // 
    console.log(this.state.loading)
    if (this.props.user && this.props.user.children && this.props.user.children.data) {
      console.log('iiiii', this.props.user.children.data[0])
      this.props.dataActions.addChild(this.props.user.children.data[0])
      if (!this.state.loading) {
        this.setState({ selectedChildren: this.props.user.children.data[0] })
      }

    }
  }

Please check screenshot:

What is the best way to stop the loop and send this.props.dataActions.addChild just one time

https://ibb.co/rm18W1b

Dashboard index code: https://pastebin.com/5V2ceAHK

Boris Civcic
  • 110
  • 1
  • 9

2 Answers2

0

1- it's not good to use setState in Update lifecycle functions like componentWillUpdate, componentDidUpdate. that can cause the loop you are getting.

2- if you want to run this action once then use componentWillMount if you need this to run on some event then make a function and call it when triggered by click or any event.

3- updating props can cause loop with componentWillRecieveProps. and the setting state can cause a loop with componentWillUpdate, componentDidUpdate.

4- you can divide your code into more components that may help you manage the states.

review your states and props again with the lifecycle will help you to find the way you need. I cannot give the exact solution by knowing the scenario, but the issues that are causing it.

  • I understand, but with componentWillMount I can't see my props(it's empty) I need to send `this.props.dataActions.addChild(this.props.user.children.data[0])` on page load And I need to get back reducer `selectedChildren: {}` (but object with first child – Boris Civcic Mar 31 '19 at 10:31
0

It is not recommended to use setState inside didUpdate life cycle. However, if you have no choice regarding the life cycle method, you have to be very careful about the condition by which you set your state

componentDidUpdate() {
    // 
    console.log(this.state.loading)
    if (this.props.user && this.props.user.children && this.props.user.children.data) {
      console.log('iiiii', this.props.user.children.data[0])
      this.props.dataActions.addChild(this.props.user.children.data[0])
      if (
        !this.state.loading &&
        this.state.selectedChildren !== this.props.user.children.data[0] // see this line here ??
      ) {
        this.setState({ selectedChildren: this.props.user.children.data[0] })
      }

    }
  }

In the code above , you should check if the selectedChildren is not already what you have in your state

this.state.selectedChildren !== this.props.user.children.data[0] 

If this selectedChildren is an object, you have to use object comparison modules, either custom made or from vendor packages. See this for more information regarding object equality

EDIT: In your code

componentDidUpdate(prevProps) {
    //

    if (
      this.props.user && 
      this.props.user.children && 
      this.props.user.children.data &&
      checkIf_prevProps.child isNotEqualTo this.props.user.children.data[0]
    ) {
      console.log('iiiii', this.props.user.children.data[0])
      this.props.dataActions.addChild(this.props.user.children.data[0])
    }
  }

So check if checkIf_prevProps.child isNotEqualTo this.props.user.children.data[0]. Or simply check for any entry in your state variable that way you know that the state has already been updated. But keep in mind that this is a dirty hack sort of thing to protect infinite rendering.

Prasanna
  • 4,125
  • 18
  • 41
  • I don't need to use `setState`. I need to send this code to action `his.props.dataActions.addChild(this.props.user.children.data[0])` but I have problem with loop. Do you have some idea how to send this code without loop – Boris Civcic Mar 31 '19 at 10:36
  • @BorisCivcic where exactly is this `loop` you are talking about ? – Prasanna Mar 31 '19 at 10:38
  • Please check the screenshot. https://ibb.co/rm18W1b SelectedChildren needs to have just one array. But I have 52 there – Boris Civcic Mar 31 '19 at 10:43
  • @BorisCivcic edited my answer, I hope it answers your query – Prasanna Mar 31 '19 at 10:45
  • Sorry...but it's same – Boris Civcic Mar 31 '19 at 11:10
  • I resolved on this way ` setTimeout(() => { if (Object.getOwnPropertyNames(this.state.userDates).length === 0) { } else { if (this.props.user && this.props.user.children && this.props.user.children.data) { this.props.dataActions.addChild(this.props.user.children.data[0]) } } this.setState({ loading: false }) }, 2500); ` – Boris Civcic Mar 31 '19 at 11:51