0

I am a newbie in React.js. While trying to understand the lifecycles in React, i stumbled upon componentWillReceiveProps. Even though i got hold of other functions, i am still not able to figure out componentWillReceiveProps. I created a small snippet where on every button click, i am incrementing the variable 'val'. When val becomes a multiple of 5, i want to change the value of 'increasing', which i am not able to do.

My Code is:

var Increment = React.createClass({
  getInitialState: function() {
    return {val: 0, increasing: false};
  },
  componentWillMount: function() {
    console.log("componentWillMount");
  },
  componentDidMount: function() {
    console.log("componentDidMount");
  },
  handleClick: function() {
    console.log("inHandleClick");
    console.log(this.state.val);
    this.setState({val: (this.state.val+1)});
  },
  componentWillReceiveProps : function(nextProps) {
    this.setState({
      increasing: (nextProps.val > this.props.val)
    });
  },
  shouldComponentUpdate: function(nextProps, nextState) {
    return (nextState.val % 5 ==0)
  },

  render: function() {
    console.log(this.state.increasing);
    return (
      <div>
        <button onClick={this.handleClick}>{this.state.val}</button>
      </div>
    );
  }
});


ReactDOM.render(<Increment />, mountNode);

Any Leads? Thanks in advance

Sukhmeet Singh
  • 130
  • 3
  • 13
  • `componentWillReceiveProps` isn't being called in your case because props are not changing, only state is changing. Perhaps you meant to use `componentWillUpdate`? That will be called if props or state change. – Aaron Beall Apr 11 '16 at 22:03
  • Aaron...can you help me with an example? – Sukhmeet Singh Apr 11 '16 at 23:57
  • @SukhmeetSingh i believe you are confused between the difference of state and props in React. You might want to have a look at [this](http://stackoverflow.com/questions/27991366/what-is-the-difference-between-state-and-props-in-react) – Calvin Apr 12 '16 at 00:53

1 Answers1

2

See this fiddle

var IncrementButton = React.createClass({
  componentWillReceiveProps : function(nextProps) {
    this.setState({
      increasing: (nextProps.val > this.props.val)
    });
  },
    render: function() {
    return (<button onClick={this.props.handleClick}>{this.props.val}</button>);
  }
});

var Increment = React.createClass({
  getInitialState: function() {
    return {val: 0, increasing: false};
  },
  handleClick: function() {
    console.log("inHandleClick");
    console.log(this.state.val);
    this.setState({val: (this.state.val+1)});
  },
  shouldComponentUpdate: function(nextProps, nextState) {
    return (nextState.val % 5 ==0)
  },
  render: function() {
    console.log(this.state.increasing);
    return (
      <div>
        <IncrementButton handleClick={this.handleClick} val={this.state.val}/>
      </div>
    );
  }
});

React.render(<Increment />, mountNode);

(Thanks to @Aaron for a more accurate description below) componentWillReceiveProps is called if your component's props get set; note it may be called even though the props haven't changed in value (You seem to take this into account with your greater than check). Since you want to compare a new value of props to an old value, you need the state to be managed outside your component. I have therefore, in this sample, split your component into two pieces by extracting the button.

mejdev
  • 3,509
  • 4
  • 24
  • 38
  • Good example of how you *should* do it, but your description of `componentWillReceiveProps` isn't true. `componentWillRecieveProps` is *only* called when props are set, not "if your component is re-rendered". In particular, the original posted code was using `setState` internally which causes `render` to be called but never calls `componentWillReceiveProps` because *only* internal state changed. – Aaron Beall Apr 12 '16 at 13:30
  • Hmm; I'm confused by the warning that Facebook has on the [Lifecycle page](https://facebook.github.io/react/docs/component-specs.html#updating-componentwillreceiveprops) which says "One common mistake is for code executed during this lifecycle method to assume that props have changed." -- that makes it sound like componentWillReceiveProps gets called many times and only a subset of those calls actually reflect changed props. – mejdev Apr 12 '16 at 13:46
  • Right the mistake is assuming that because the props were *set* they have somehow *changed*, but they might likely be the exact same props as before. However, if a component only sets *state*, it will re-render but it will *not* call `componentWillReceiveProps` since the *props* were never set, only the state was set. By contrast, `componentWillUpdate` will be called if *either* props or state were set. – Aaron Beall Apr 12 '16 at 13:53
  • Ahh, I see. Well I will update my answer with this more accurate description :) Thanks! – mejdev Apr 12 '16 at 14:00