Codementor Events

I wish I knew these before diving into React

Published Jan 18, 2018Last updated Jul 16, 2018
I wish I knew these before diving into React

At OpsGenie, we had a deep dive into React for our Badges project. I learned many new things & made many mistakes. Some of my learnings are subjective, but I thought they may help other people to learn React and avoid making the same mistakes. Long story short, these are the things that really helped me.

1. By default, setState triggers a re-render

The default behavior of React is to re-render on every state change, and most of the time it is okay to rely on this. However, re-rendering unnecessarily wastes cycles which is not a good practice.

Each component has a method called shouldComponentUpdate and it is called everytime you change state or pass new props from the parent component. React decides whether to re-render or not according to the return value of shouldComponentUpdate.

By default, shouldComponentUpdate returns true, but you can override it to return false for cases that you do not want a re-render. Here is an example:

shouldComponentUpdate(nextProps, nextState) {
    const vitalPropsChange = this.props.bar !== nextProps.bar;
    const vitalStateChange = this.state.foo !== nextState.foo;    
    return vitalPropsChange || vitalStateChange;
}
// React will not re-render the component unless vitalPropsChange
// or vitalStateChange is true.

Important notes:

  1. Setting shouldComponentUpdate wrongly or forgetting that you set it can cause major problems since your component may not be updated as expected.
  2. Running computations in shouldComponentUpdate can be expensive in terms of performance and effort, so you should make sure it is worth it. I strongly recommend you to use React’s Performance Tools to check the number of wasted cycles before and after using shouldComponentUpdate. It has a very simple usage:
Perf.start() 
// React operations in-between are recorded for analyses.
Perf.stop()
Perf.printWasted()

2. setState updates the local state asynchronously

You should think of setState as a request rather than an immediate command. It is not guaranteed that the state changes are applied instantly after a setState call.

A common mistake is to read this.state right after calling setState . In general, it is not reliable to use this.state inside the setState method.

// this.state.value is initially 0
this.setState({value: this.state.value + 1});
this.setState({value: this.state.value + 1});
this.setState({value: this.state.value + 1});
// this.state.value is 1 instead of 3

If you need to update the state based on the previous state, best practice is using the updater function which is the first argument of setState(updater, [callback]).

An example of passing an updater function to setState :

this.setState((prevState) => {  
   return {value: prevState.value + 1};
});

Bonus: What is the second argument, callback ?

It is an optional callback function, executed after setState is completed and the component is re-rendered. However, componentDidUpdate is recommended for such logic instead of callback in the official docs.

For more detailed information I recommend you to check this part of the official document.

3. Component Lifecycle is Important!

The first step to have a happy life with React components is to understand the component life cycle. Each React component has methods that you can use to run your code at particular times in component’s lifecycle. In order to use them correctly, you should grasp the call order of lifecycle methods. We can simply divide lifecycle into three parts:

Mounting: an instance of the component is being created and inserted into the DOM.

Updating: component is being re-rendered, can be caused by changes of props or state.

Unmounting: component is being removed from the DOM.

It is very important to understand how these methods work. This post is great for understanding lifecycle methods and their usage. I also strongly recommend you to check this part of the official documents.

4. Use componentWillReceiveProps

If you want to update the state in response to props changes, this is the method you need. Compare this.props with nextProps and if there is a significant change, act on it.

componentWillReceiveProps(nextProps){
  if(this.props.foo !== nextProps.foo){
    this.whenFooChanges();
  }
  if(this.props.bar !== nextProps.bar){
    this.whenBarChanges();
  }
}

Two important notes here:

  1. React may call componentWillReceiveProps even if the props have not changed, so comparing this.props and nextProps is important.
  2. componentWillReceiveProps is invoked before a mounted component receives new props, this means React doesn’t call componentWillReceiveProps with initial props during mounting.

5. Use React Developer Tools

React Developer Tools lets you inspect the React component hierarchy, components’ props and state. It is very useful in many cases because React is all about components. It exists both as a browser extension (for Chrome and Firefox), and as a standalone app.

6. Use Create React App

Facebook’s Create React App lets you create React apps with no build configuration. It is very simple to use and has a great Github readme. You only need to have Node >= 6 and it works on macOS, Windows, and Linux.


Interested in more React posts?

You learned the basics of React, now what?
How to Organize React Files Before It’s Messed Up


Originally published on the OpsGenie Engineering blog.

Discover and read more posts from Canberk Morelli
get started
post commentsBe the first to share your opinion
Vijay Thirugnanam
6 years ago

One thing that I learnt that is missed out here is Functional components. If you are using too many stateful components, there is something wrong with your design. Most of your components should be functional components when you use React with Redux or Mobx.

Robert Mirro
6 years ago
Canberk Morelli
6 years ago

I believe many React beginners can benefit from this post. So, why not share it with more people?

Mark Tellez
6 years ago

How about this? He wanted the codementor community to be able to read it? I never understood the mentality that if it is on one place on the interwebs it doesn’t need to be anywhere else. It makes no sense.

Thanks for the post.

Robert Mirro
6 years ago

I never understood the mentality that drives one to easily jump to conclusions.

I asked a question because I initially thought there may have been updates in the “new” post but wasn’t able to detect any.

Thanks for the post.

Show more replies