Enter Your Email Address to Watch This Lesson

Your link to unlock this lesson will be sent to this email address.

Unlock this lesson and all 986 of the free egghead.io lessons, plus get React content delivered directly to your inbox!



Existing egghead members will not see this. Sign in.

Control React Component Updates When New Props Are Received

3:30 React lesson by

The React component lifecycle will allow you to update your components at runtime. This lesson will explore how to do that. componentWillReceiveProps gives us an opportunity to update state by reacting to a prop transition before the render() call is made. shouldComponentUpdate allows us to set conditions on when we should update a component so that we are not rendering constantly. componentDidUpdate lets us react to a component updating.

Get the Code Now
click to level up

egghead.io comment guidelines

Avatar
egghead.io

The React component lifecycle will allow you to update your components at runtime. This lesson will explore how to do that.

Avatar
joyfeel

After 0.13 version, setProps() is deprecated.

How to use it by the other way?

Avatar
Pyong-Hwa

It would be better to mention this.setProps is deprecated..

In reply to egghead.io
Avatar
Pyong-Hwa

I'm curious, either.

In reply to joyfeel
Avatar
Sequoia McDowell

Wish author had explained what componentWillRecieveProps means. I mean, I can guess & I am 90% certain I understand when it fires, but it would be nice to not have to guess :)

Avatar
Joseph

componentWillRecieveProps is covered in the lesson beginning at 0:42.

In reply to Sequoia McDowell
Avatar
HaveF

{"error":"Transcript not found or finished."}

Avatar
Jake

I'm a little confused at this point as to how the componentWillReceiveProps lifecycle method works in this instance.

I understand that it fires when new properties are passed to a component, but what doesn't currently make sense to me is that we only seem to have a single component in this example - App.

When App.defaultProps = { val: 0 } is expressed, it seems as though the App is giving itself properties -is that correct? Why isn't this State?

Is there an advantage to using Props instead of State? Is it because down the line most components can be expected to use Props?

TL:DR; how come the App is giving itself properties rather than manipulating internal State?

Avatar
Joseph

The advantage of using Props instead of State is increased composability. Meaning that a component that only responds to props is almost always a simpler and more reusable component with little or no side effects presented.

I chose to use Props as the mechanism for triggering these lifecycle methods in the lesson specifically to teach the use of componentWillReceiveProps which only responds to Props.

None of this is meant to imply that using State is wrong, just that Props made more sense in this particular example.

defaultProps is a useful property for instantiating a component that may or may not have received any props.

In reply to Jake
Avatar
Elgs

When update is called, it looks like a whole new <App> is put in the DOM to replace the old <App>. If this is the case, does componentWillReceiveProps compare the props between the old and the new <App>? Or does React keep track of of all <App>s render() put in the DOM and give them each a sequential number to track them between each render() when there are more than one <App>s?

Avatar
Alex Vallejo

"on 5, we get our update" should really be "on 5, we get our render()" since shouldComponentUpdate does not prevent update(), but it does prevent render()

In this lesson, we're going to talk about the updating lifecycle methods that are available to us in our components.

To get us started, I'm going to return a <button>. It's going to have an onClick handler of this.update.bind.(this). It's inner html is going to be this.props.val. We're going to get that val from defaultProps. I'm going to say app.defaultProps equals, we'll set our val to 0.

App.js

import React from 'react';
import ReactDOM from 'react-dom';

class App extends React.Component {
  return (
    <button onClick={this.update.bind(this)}>
      {this.props.val}
    </button>
  )
}

App.defaultProps = {val: 0}

export default App

We're going to go ahead and create this update method. We're going to get a little tricky with this one. We're actually going to rerender our entire component.

update() {
  ReactDOM.render(
    <App val={this.props.val+1} />, 
    document.getElementById('root'))
}

I'm going to say ReactDOM.render(<App />). I'm going to target the same <div> that we're targeting index.js. Here, we're going to say val equals, and we're going to say this.props.val+1. Every time we render it, we're going to increment by one that value of val. If we save that and try it out, each time we click on this, it get incremented by one because of its new props.

I'm going to add to this some state. I'm going to set up our constructor. We'll call super() to get our context. I'm going to set the state to equal. We're going to have a value here for increasing. I'm going to set that to false. What we want to do is determine if the new prop that's coming in of val is increasing from the previous prop or not.

constructor() {
  super();
  this.state = {increasing: false}
}

The first updating lifecycle method we can look at is componentWillReceiveProps. This means that new properties are coming in. We get access to those props right here, with this variable, nextProp. What we're going to do is we're going to set our state of increasing to nextProps.val > this.props.val.

componentWillReceiveProps(nextProps){
  this.setState({increasing: nextProps.val > this.props.val})
}
render(){
  console.log(this.state.increasing)
  return (
    ...
  )
}

Then here, in our render method, we'll simply console.log(this.state.increasing). The first time through, that should not be true. Each subsequent rerender it should be true.

We'll save that and open up our dev tools. Here's the first firing. We'll click on this guy, and from here on out, it's going to be true, because we're constantly increasing that value.

Increasing True

The next updating phase we can look at is shouldComponentUpdate. This is going to take in our nextProps, as well as our nextState. What I'm going to do here is say if the nextProps not val is a multiple of five, then, we'll go ahead and update it.

shouldComponentUpdate(nextProps, nextState) {
  return nextProps.val % 5 === 0;
}

Here, it's simply returning a true or false. It's important to note that this doesn't prevent our state, and of course, not our props, from being updated. It simply prevents a rerender. If I save that, two, three, four five, we get our update, one, two, three, four, five, we get our update. Again, the state has actually been changed.

ShouldComponentUpdate

The last one we can take a look at is componentDidUpdate, which takes in our prevProps, as well as our previousState. Here, we'll just log out prevProps, and the actual prevProps. Here in the browser, we'll click one, two, three, four, five. Whoops.

componentDidUpdate(prevProps, prevState) {
  console.log(`prevProps: ${prevProps.val}`)
}

Let's go ahead and get the val off of that guy. prevProps.val. One, two, three, four, five. We can see our previous prop was 4, that indicates that our state is actually being updated while our props are actually being updated. We can see from our state we've got true, and our prop is now 4. If we go one, two, three, four, five, we get nine.

prevProps



HEY, QUICK QUESTION!
Joel's Head
Why are we asking?