RangeError stack size @ Render: if include with props ( React )


#1

Previously wrote about issue i was having checking and setting State without a full page reload:
https://github.com/kadirahq/flow-router/issues/372 & https://forums.meteor.com/t/flowrouter-go-how-getinitialstate/12427

Did not get so much help understanding that so did just grind it out until i found something working and that was putting this in my render function

  render: function () {

    // check if userId is present in upvoters array.
    if (_.include(this.props.video.upvoters, this.props.userId)) {
    this.setState({like:true});
    } else {
    this.setState({like:false});
  }

Function wise this is doing what i want but it’s producing: Uncaught RangeError: Maximum call stack size exceeded

Removing the code above will eliminate the error so i guess i’m still doing it wrong but it’s the only way i manage to get the function / result i want. A little confusing is also the reference: at React.createClass.getMeteorData (like.jsx:14)

11 mixins: [ReactMeteorData],
12  getMeteorData() {
13   return {
14      currentUser: Meteor.user(),   
15    
16   };    
17 },

All help / input is very much appreciated.


#2

Adding setState in the render function can cause a re-render and an infinite loop! Not a good idea to put the setState here. The shouldComponentUpdate can be used to prevent the re-render if the state has not changed.

One would like to ask, if “like” should even be in the state? You can set a variable in the render function and use that to render the component as needed.


#3

Thanks for the input.
Do you have any references or examples that you can show or link?


#4

Got back to this issue today, a few day’s +wiser in this stack. I did feel that i wanted to use React functions where it’s possible.

shouldComponentUpdate
This function will trigger a loop because it will update on: new props or state are being received so changing a state will simply trigger it to run again and set a new state and so on… creating a loop

componentWillReceiveProps
Using componentWillReceiveProps i could get the correct lifecycle.

This is my current code

  getInitialState: function () {
    if (_.include(this.props.video.upvoters, this.props.userId)) {
      return {like: true}
    } else {
      return {like: false};
    }
  },

   componentWillReceiveProps:function () {
     if (_.include(this.props.video.upvoters, this.props.userId)) {
       this.setState({like:true});
     } else {
       this.setState({like:false});
     }
   },

Am sure there is room for improvement but at this point am getting what i want.