question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

onvaluechanged -> setState -> infinite loop

See original GitHub issue

Are you requesting a feature, reporting a bug or asking a question?

Question

What is the current behavior?

state grows exponentially each time i choose an option in my survey.

What is the expected behavior?

setState is called once every time an option is updated without interfering with the survey.

Test code

    onValueChanged = (model) => (e) => {
        fetch('http://localhost:5000/api/post', {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(model.data)
        }).then(json => {
            this.setState({githubData: json});
            }
        );
    };

Specify your

  • browser: Firefox
  • surveyjs platform: React
  • surveyjs version: Latest

I am trying to call my api everytime a user selects an option or changes it. With that information i am trying to update a sidebar. But if i call setstate in onvaluechanged first the state grows exponentially and second the options don’t reset. So if normally i can choose one of three options, with setstate enabled i can choose all three. Any ideas?

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:9 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
dmitrykurmanovcommented, Sep 6, 2018

@xadie yes you are right! @swilso793 We recommended to create model and add event listeners only once. For example:

  constructor(props) {
    super(props);
    var model = new Survey.Model(this.json);
    model.onComplete.add(this.onComplete);
    model.onValueChanged.add(this.onValueChanged);
   ...

    this.state = {
      ...
      surveyModel: model
    };
  }
  ...
  render() {
    ...
    return <Survey.Survey model={this.state.surveyModel} />;
  }

could you please try this approach?

2reactions
xadiecommented, Sep 5, 2018

It’s not a React Issue. It’s an issue in Survey.js-react. The cause of this is a combination of missuse of the componentWillReceiveProps event in reactSurvey.tsx in combination with the updateSurvey function in reactSurvey.tsx

protected updateSurvey(newProps: any) {
    if (newProps) {
      if (newProps.model) {
        this.survey = newProps.model;
      } else {
        if (newProps.json) {
          this.survey = new ReactSurveyModel(newProps.json);
        }
      }
    } else {
      this.survey = new ReactSurveyModel();
    }
    if (newProps) {
      for (var key in newProps) {
        if (key == "model" || key == "children") continue;
        if (key == "css") {
          this.survey.mergeCss(newProps.css, this.css);
          continue;
        }
        if (
          key.indexOf("on") == 0 &&
          this.survey[key] &&
          this.survey[key].add
        ) {
          let funcBody = newProps[key];
          let func = function(sender, options) {
            funcBody(sender, options);
          };
          this.survey[key].add(func); //<= will re-add already subscribed listeners.... 
        } else {
          this.survey[key] = newProps[key];
        }
      }
    }

Instead of replacing all listeners on an Event on each updateSurvey-call they are added.
Whenever the react event componentWillReceiveProps is triggered on the Survey Component it will add all by prop provided event listeners on top on the old list over the lifetime of the component. Basically the function bleeds old-state values into new-state values.

Read more comments on GitHub >

github_iconTop Results From Across the Web

ReactJS - Infinite loop, setState onChange method
There is an infinite loop because you call this.handleChange in your editor component when a change occurs in the CodeMirror instance.
Read more >
How to Solve the Infinite Loop of React.useEffect()
useEffect() hook because it can generate infinite loops. ... const onChange = ({ target }) => setValue(target.value);. return (.
Read more >
setState -> infinite loop · Issue #1308 · surveyjs/survey-library
setState is called once every time an option is updated without interfering with the survey. Test code. onValueChanged = (model) => (e) =>...
Read more >
Why does my code cause an infinite loop and how do I fix ...
I am trying to delete a task from an array inside the parent's state so the child gets deleted when re-rendering but it...
Read more >
Infinite loop when changing state from onChange-Reactjs
Coding example for the question React - Infinite loop when changing state from onChange-Reactjs.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found