As everything is in programming, it’s a tradeoff, let’s see why.

Advantages and Disadvantages of React defaults:

While using defaultProps is the best practice at the moment, it looks like this will change in the upcoming versions of React.

The main advantage defaultProps has is it gives us a unified way of setting default values to props in both class components and functional components. The second advantage is that the syntax is simple and straightforward.

The main problem with defaultProps , lies in its implementation.

Let’s have a look at React.createElement implementation at the latest stable version (16.8.6).

Simplified version of createElement taken from React repo in GitHub

We can see that some stuff happen when calling to createElement with the props object, but the main issue is the defaultProps check. If we have defaultProps , we iterate over them and check if we already have a value in the props object, in case we don’t have a value we assign it the default. This happens every time we call createElement .

Let’s have a look at a small timing example I took with the Greet component we just built (The test was made in a development build of React).

All I did was adding console.time() at the start of createElement and console.timeEnd() at the end.

With defaultProps, createElement time: 0.01123046875ms

Without defaultProps, createElement time: 0.003662109375ms

That’s three times slower for that simple component and it contains only two defaultProps !

Just a quick disclosure, this doesn’t mean adding defaultProps will increase the render time by three, it just adds some milliseconds as it iterates over the defaults.

Advantages and Disadvantages of ES6 Defaults:

The main advantage default values has is that it’s a native syntax added in ES6 and supported in almost all browsers (except IE11) as a part of destructuring assignment.

In my opinion, the bigger problem with default values is that they create a difference between how we set default values in class components and how we set them in functional components, as setting a default value to a prop isn’t available in a class, the old class components will still have to use the old propTypes way, thus creating another difference between these two types of components. This problem will disappear in time since the use of class components should decline with hooks.

For the second problem we’ll have to change the Greet component a bit,

let’s change the component so it will accept a user object instead of firstName and lastName .

const Greet = ({user = { firstName: 'John', lastName: 'Doe' }}) => {

return (<div>{`Hi ${user.firstName} ${user.lastName}`}</div>)

}

What’s the problem with the example we created? That’s right, immutability. The object we created as a default value will be recreated in every function call, so if we pass it down to a child component, the component will get a new reference every time and will cause a render on each parent render.

To fix that problem we will need to create the default value globally as a const so the reference won’t change:

const defaultUser = { firstName: 'John', lastName: 'Doe' }; const Greet = ({user = defaultUser}) => {

return (<div>{`Hi ${user.firstName} ${user.lastName}`}</div>)

}

When using default values on latest browsers that don’t need to transpile destructuring assignment, it can even lead to a smaller bundle size. On the other hand, when using it in browsers that do need to transpile it, it may lead to a bigger bundle size since destructring assignment default values transpiles pretty weird.

I made a small example based on CRA with only prop-types and styled-components added. The example is made of 10 components, each one of them contains defaultProps .

Let’s take a look at a bundle size comparison after gzip:

Without defaultProps and transpile of default values: 55.969KB

Without defaultProps and not transpiling default values: 55.945KB

With defaultProps : 55.979KB

It looks like the difference to the bundle size is minimal.

Summing it up:

React def. values lets us have a unified way of setting default values.

React def. values will be slower the more default values you set.

ES6 def. values may reduce your bundle size if deploying to browsers that already have destructuring assignment enabled.

When using ES6 def. values you have to remember the pitfalls and create non primitive values upfront so they won’t cause a render on child elements.

The React team decided on ES6 def. values as a way to set default values for functional components. A warning was already added as a part of the process to deprecate defaultProps in functional components.

It looks like we will see changes like what I talked about in the upcoming version of React, and it’s all a part of making React better for us the developers and for our users. The React team is working hard on tackling performance issues and changing the way we see the web now.

Keep up the great work React team ❤️

Hope I sold it well, but if you have any questions, feel free to ask.

I’m here and also on twitter.

Thanks for reading!