javascript - Swapping elements in React.js and getting <error> -


so have deck of study cards, , have link start study session top. after user has finished study session, not want user access the study session link 2 minutes. instead of link have timer counting down 2 minutes 0 using timeleft state. after 2 minutes, timer goes away , replaced link study session setting state "link" in componentdidupdate. works expected, except react slows down rendering of deck page. code follows:

/** @jsx react.dom */ var cardmodel = require("../models/card.js"); var card = react.createfactory(require("./card.jsx")); //var backbonemixin = require("../../backbonemixin.js");  var deckshow = react.createclass({   //mixins: [backbonemixin],   getinitialstate: function() {     return {elapsedtime: this.settime(), timeleft: 0, cards: this.props.cards, cardscollection: [], cardshow: "question", empty: "none" }   },    componentdidmount: function () {     this.props.cardcollection.fetch();     var boxes = this.getboxstate(this.props.deck)     this.setstate({timeleft: this.props.delay - this.state.elapsedtime})     this.interval = setinterval(this.countdown, 1000)     var startbox = [];     var = 0;     while (i <= (this.props.deck.get("session_num") % 5)) {       startbox.concat(boxes[i])       += 1;     }      if ((this.props.deck.get("cards").length > 0) && (this.state.elapsedtime >= this.props.delay || this.props.deck.get("last_session") === null)) {       this.setstate({empty: "link"});     } else if (this.props.deck.get("cards").length > 0 && startbox.length === 0) {       this.setstate({empty: "timer"})       //settimeout(this.setstate({empty: "link"}), this.state.timeleft)     }     else{       this.setstate({empty: "none"});     }   },    componentdidupdate: function(nextprops, nextstate) {     this.props.deck.on("sync", function(){       this.forceupdate();     }, this)      if (this.state.timeleft <= 0) {       clearinterval(this.interval)       this.setstate({empty: "link"})       this.forceupdate();     }   },    componentwillupdate: function(){   //      var = this;   //      if (this.state.elapsedtime <= 0) {   //          that.setstate({empty: that.link})   //      }   },    componentwillunmount: function(){     clearinterval(this.interval);   },    settime: function(){     var last = this.props.deck.get("last_session") || date.now();     return date.now() - last;   },    getboxstate: function(deck) {     var boxstate = [[],[],[],[],[]]     var deckcards = deck.get("cards");     (var = 0; < deckcards.length; i++) {       boxstate[deckcards[i].box_id].push(deckcards[i])     }      return boxstate;   },    countdown: function() {     this.setstate({timeleft: this.state.timeleft - 1000})   },    handlesubmit: function(event) {     event.preventdefault();     var question = this.refs.question.getdomnode().value.trim();     var answer = this.refs.answer.getdomnode().value.trim();     if ((!question) || (!answer)) {       return;     }       this.refs.question.getdomnode().value = '';     this.refs.answer.getdomnode().value = '';     var cards = this.props.cardcollection.models[0].get("objects")      var newcard = {       question: question,       answer: answer,       deck_id: this.props.id,       box_id: 0     }      this.props.cardcollection.create(newcard, {wait: true})     var cardarr = this.state.cards     cardarr.push(newcard)     this.setstate({empty: "link"});     this.setstate({cards: cardarr})     return;   },    render: function() {     var header = "deck: " + this.props.deck.get("name");      var cardslist = this.props.cards.map(function(card) {       return <card box={card.box_id}             key={card.id}             cardquestion={card.question}             cardanswer={card.answer}             text={card.answer} />     });      var view;     var empty = this.state.empty;     var = this;      var elapsed = this.state.timeleft;     var none = <p>{"there no cards"}</p>     var timer = <p>{"time till next: " + math.floor(elapsed/60000) + ":" + math.floor((elapsed % 60000)/1000)}</p>     var link = <a href={"#/decks/" + this.props.id + "/study"}>{"study mode"}</a>      if (this.state.empty === "link") {       view = link;     } else if (this.state.empty === "timer") {       view = timer;     } else {       view = none;     }      return (       <div classname="cardlist">         <h2>{header}</h2>         <div id="study-mode">           {view}         </div>         <ul id="deck-index">{cardslist}</ul>         <div classname="input">           <form onsubmit={this.handlesubmit} classname="form-horizontal">             <div classname="form-group">               <input                 type="text"                 ref="question"                 placeholder="add new question" />               <br />               <input                 type="textarea"                 ref="answer"                 placeholder="add answer" />               <br />               <input type="submit" value="add card" />             </div>           </form>         </div>       </div>     );   } });  module.exports = deckshow; 

the error trace follows:

reactelement @ react.js:9890reactelement.createelement @ react.js:9972reactclass.createclass.render @ react.js:8288reactcompositecomponentmixin._rendervalidatedcomponentwithoutownerorcontext @ react.js:6925reactcompositecomponentmixin._rendervalidatedcomponent @ react.js:6951reactperf.measure.wrapper @ react.js:13371reactcompositecomponentmixin._updaterenderedcomponent @ react.js:6882reactcompositecomponentmixin._performcomponentupdate @ react.js:6863reactcompositecomponentmixin.updatecomponent @ react.js:6783reactperf.measure.wrapper @ react.js:13371reactcompositecomponentmixin.receivecomponent @ react.js:6647reactreconciler.receivecomponent @ react.js:14131reactchildreconciler.updatechildren @ react.js:4779reactmultichild.mixin._updatechildren @ react.js:12900reactmultichild.mixin.updatechildren @ react.js:12874reactdomcomponent.mixin._updatedomchildren @ react.js:7862reactdomcomponent.mixin.updatecomponent @ react.js:7713reactdomcomponent.mixin.receivecomponent @ react.js:7697reactreconciler.receivecomponent @ react.js:14131reactcompositecomponentmixin._updaterenderedcomponent @ react.js:6884reactcompositecomponentmixin._performcomponentupdate @ react.js:6863reactcompositecomponentmixin.updatecomponent @ react.js:6783reactperf.measure.wrapper @ react.js:13371reactcompositecomponentmixin.receivecomponent @ react.js:6647reactreconciler.receivecomponent @ react.js:14131reactchildreconciler.updatechildren @ react.js:4779reactmultichild.mixin._updatechildren @ react.js:12900reactmultichild.mixin.updatechildren @ react.js:12874reactdomcomponent.mixin._updatedomchildren @ react.js:7862reactdomcomponent.mixin.updatecomponent @ react.js:7713reactdomcomponent.mixin.receivecomponent @ react.js:7697reactreconciler.receivecomponent @ react.js:14131reactcompositecomponentmixin._updaterenderedcomponent @ react.js:6884reactcompositecomponentmixin._performcomponentupdate @ react.js:6863reactcompositecomponentmixin.updatecomponent @ react.js:6783reactperf.measure.wrapper @ react.js:13371reactcompositecomponentmixin.receivecomponent @ react.js:6647reactreconciler.receivecomponent @ react.js:14131reactchildreconciler.updatechildren @ react.js:4779reactmultichild.mixin._updatechildren @ react.js:12900reactmultichild.mixin.updatechildren @ react.js:12874reactdomcomponent.mixin._updatedomchildren @ react.js:7862reactdomcomponent.mixin.updatecomponent @ react.js:7713reactdomcomponent.mixin.receivecomponent @ react.js:7697reactreconciler.receivecomponent @ react.js:14131reactcompositecomponentmixin._updaterenderedcomponent @ react.js:6884reactcompositecomponentmixin._performcomponentupdate @ react.js:6863reactcompositecomponentmixin.updatecomponent @ react.js:6783reactperf.measure.wrapper @ react.js:13371reactcompositecomponentmixin.receivecomponent @ react.js:6647reactreconciler.receivecomponent @ react.js:14131reactchildreconciler.updatechildren @ react.js:4779reactmultichild.mixin._updatechildren @ react.js:12900reactmultichild.mixin.updatechildren @ react.js:12874reactdomcomponent.mixin._updatedomchildren @ react.js:7862reactdomcomponent.mixin.updatecomponent @ react.js:7713reactdomcomponent.mixin.receivecomponent @ react.js:7697reactreconciler.receivecomponent @ react.js:14131reactcompositecomponentmixin._updaterenderedcomponent @ react.js:6884reactcompositecomponentmixin._performcomponentupdate @ react.js:6863reactcompositecomponentmixin.updatecomponent @ react.js:6783reactperf.measure.wrapper @ react.js:13371reactcompositecomponentmixin.receivecomponent @ react.js:6647reactreconciler.receivecomponent @ react.js:14131reactcompositecomponentmixin._updaterenderedcomponent @ react.js:6884reactcompositecomponentmixin._performcomponentupdate @ react.js:6863reactcompositecomponentmixin.updatecomponent @ react.js:6783reactperf.measure.wrapper @ react.js:13371reactcompositecomponentmixin.performupdateifnecessary @ react.js:6680reactreconciler.performupdateifnecessary @ react.js:14149runbatchedupdates @ react.js:14899mixin.perform @ react.js:16625mixin.perform @ react.js:16625assign.perform @ react.js:14843flushbatchedupdates @ react.js:14923reactperf.measure.wrapper @ react.js:13371nested_updates.close @ react.js:14799mixin.closeall @ react.js:16698mixin.perform @ react.js:16639assign.perform @ react.js:14843flushbatchedupdates @ react.js:14923reactperf.measure.wrapper @ react.js:13371nested_updates.close @ react.js:14799mixin.closeall @ react.js:16698mixin.perform @ react.js:16639assign.perform @ react.js:14843flushbatchedupdates @ react.js:14923reactperf.measure.wrapper @ react.js:13371nested_updates.close @ react.js:14799mixin.closeall @ react.js:16698mixin.perform @ react.js:16639assign.perform @ react.js:14843flushbatchedupdates @ react.js:14923reactperf.measure.wrapper @ react.js:13371nested_updates.close @ react.js:14799mixin.closeall @ react.js:16698mixin.perform @ react.js:16639assign.perform @ react.js:14843flushbatchedupdates @ react.js:14923reactperf.measure.wrapper @ react.js:13371nested_updates.close @ react.js:14799mixin.closeall @ react.js:16698mixin.perform @ react.js:16639assign.perform @ react.js:14843flushbatchedupdates @ react.js:14923reactperf.measure.wrapper @ react.js:13371nested_updates.close @ react.js:14799mixin.closeall @ react.js:16698mixin.perform @ react.js:16639assign.perform @ react.js:14843flushbatchedupdates @ react.js:14923reactperf.measure.wrapper @ react.js:13371nested_updates.close @ react.js:14799mixin.closeall @ react.js:16698mixin.perform @ react.js:16639assign.perform @ react.js:14843flushbatchedupdates @ react.js:14923reactperf.measure.wrapper @ react.js:13371nested_updates.close @ react.js:14799mixin.closeall @ react.js:16698mixin.perform @ react.js:16639assign.perform @ react.js:14843flushbatchedupdates @ react.js:14923reactperf.measure.wrapper @ react.js:13371nested_updates.close @ react.js:14799mixin.closeall @ react.js:16698mixin.perform @ react.js:16639assign.perform @ react.js:14843flushbatchedupdates @ react.js:14923reactperf.measure.wrapper @ react.js:13371nested_updates.close @ react.js:14799mixin.closeall @ react.js:16698mixin.perform @ react.js:16639assign.perform @ react.js:14843flushbatchedupdates @ react.js:14923reactperf.measure.wrapper @ react.js:13371nested_updates.close @ react.js:14799mixin.closeall @ react.js:16698mixin.perform @ react.js:16639assign.perform @ react.js:14843flushbatchedupdates @ react.js:14923reactperf.measure.wrapper @ react.js:13371nested_updates.close @ react.js:14799mixin.closeall @ react.js:16698mixin.perform @ react.js:16639assign.perform @ react.js:14843flushbatchedupdates @ react.js:14923reactperf.measure.wrapper @ react.js:13371nested_updates.close @ react.js:14799mixin.closeall @ react.js:16698mixin.perform @ react.js:16639assign.perform @ react.js:14843flushbatchedupdates @ react.js:14923reactperf.measure.wrapper @ react.js:13371nested_updates.close @ react.js:14799mixin.closeall @ react.js:16698mixin.perform @ react.js:16639assign.perform @ react.js:14843flushbatchedupdates @ react.js:14923reactperf.measure.wrapper @ react.js:13371nested_updates.close @ react.js:14799mixin.closeall @ react.js:16698mixin.perform @ react.js:16639assign.perform @ react.js:14843flushbatchedupdates @ react.js:14923reactperf.measure.wrapper @ react.js:13371nested_updates.close @ react.js:14799mixin.closeall @ react.js:16698mixin.perform @ react.js:16639assign.perform @ react.js:14843flushbatchedupdates @ react.js:14923reactperf.measure.wrapper @ react.js:13371nested_updates.close @ react.js:14799mixin.closeall @ react.js:16698mixin.perform @ react.js:16639assign.perform @ react.js:14843flushbatchedupdates @ react.js:14923reactperf.measure.wrapper @ react.js:13371nested_updates.close @ react.js:14799mixin.closeall @ react.js:16698mixin.perform @ react.js:16639assign.perform @ react.js:14843flushbatchedupdates @ react.js:14923reactperf.measure.wrapper @ react.js:13371nested_updates.close @ react.js:14799mixin.closeall @ react.js:16698mixin.perform @ react.js:16639assign.perform @ react.js:14843flushbatchedupdates @ react.js:14923reactperf.measure.wrapper @ react.js:13371nested_updates.close @ react.js:14799mixin.closeall @ react.js:16698mixin.perform @ react.js:16639assign.perform @ react.js:14843flushbatchedupdates @ react.js:14923reactperf.measure.wrapper @ react.js:13371nested_updates.close @ react.js:14799mixin.closeall @ react.js:16698mixin.perform @ react.js:16639assign.perform @ react.js:14843

calling this.forceupdate() inside of componentdidupdate causing infinite recursion in code. componentdidupdate update method called every time props or state of component change , when forceupdate() called. therefore componentdidupdate -> forceupdate -> componentdidupdate -> forceupdate -> ......[infinite recursion].

to fix issue:

  1. move this.props.deck subscription componentdidupdate componentdidmount. subscription needs added when component mounted, not every time updated.
  2. remove other forceupdate() call componentdidupdate