Without using the destructuring syntax getting multiple values out of an array can be quite cumbersome. You would do something like this:
const items = ['car', 'bike', 'plane'];
const car = items[0];
const bike = items[1];
const plane = items[2];
console.log(car); // 'car'
console.log(bike); // 'bike'
console.log(plane); // 'plane'
With the destructuring assignment syntax this can be written like this:
const items = ['car', 'bike', 'plane'];
const [car, bike, plane] = items;
console.log(car); // 'car'
console.log(bike); // 'bike'
console.log(plane); // 'plane'
This syntax also works with nested arrays:
const items = ['car', ['bike', 'plane'], ['boat']];
const [car, [bike, plane], [boat]] = items;
console.log(car); // 'car'
console.log(bike); // 'bike'
console.log(plane); // 'plane'
console.log(boat); // 'boat'
You can combine the destructuring syntax with the rest syntax:
const items = ['car', 'bike', 'plane', 'boat'];
const [car, ...transportation] = items;
console.log(car); // 'car'
console.log(transportation); // ['bike', 'plane', 'boat']
The destructuring assignment syntax with Objects
Destructuring with Objects helps you assigning property values to variables. I only specify the binded property, and this will be bound to the value to of the property.
const car = {
brand: 'ferrari',
type: 'sportscar',
horsepower: 600,
wheels: 4
};
const { brand, type } = car;
console.log(brand); // ferrari
console.log(type); // sportscar
Just like with Arrays you can also use this syntax with nested objects:
const car = {
brand: 'ferrari',
type: 'sportscar',
engine: {
horsepower: 600,
liters: 4,
fuel: 'gas'
},
wheels: 4
};
const { engine: { horsepower } } = car;
console.log(horsepower); // 600
Aplication of destructuring
The destructuring syntax can help when accepting parameters in functions. Instead of requesting specific arguments in a specific order it would be a lot easier to just pass one object and then expose only the needed properties using the destructuring syntax:
const carFunction = ({ brand, engine: { horsepower, liters }}) => {
return `${brand} with engine of ${horsepower} horsepower and ${liters} liters`
}
const car = {
brand: 'ferrari',
type: 'sportscar',
engine: {
horsepower: 600,
liters: 4,
fuel: 'gas'
},
wheels: 4
};
console.log(carFunction(car)); // ferrari with engine of 600 horsepower and 4 liters
Last but not least the destructuring syntax is very helpful when importing from CommonJS modules. Most likely the module exports more than you need and with this syntax you can avoid cluttering the namespace.
const { session } = require('passport');
session();
// instead of
const passport = require('passport');
passport.session();
As a general rule use const
instead of let
while destructuring props. Props are not allowed to be mutated. Using const
would prevent reassigning variables which goes against immutable data concepts a little I think? If the variable won’t be reassigned, it should really just be const as that’s its purpose.
Let’s consider a parent component called Properties in our application:
import React, { Component } from 'react';
class Properties extends Component {
constructor() {
super();
this.properties = [
{
title: 'Modern Loft',
type: 'Studio',
location: {
city: 'San Francisco',
state: 'CA',
country: 'USA'
}
},
{
title: 'Spacious 2 Bedroom',
type: 'Condo',
location: {
city: 'Los Angeles',
state: 'CA',
country: 'USA'
}
},
];
}
render() {
return (
<div>
<Listing listing={this.properties[0]} />
<Listing listing={this.properties[1]} />
</div>
);
}
}
Properties
component to child Listing
component
Functional Child Component implementation passing down the props from above parent Listing
is a pure functional component as a child of Properties
component
That is the case, when In this example, we want to pass down a listing object from our array of properties for the child component named Listing to render.
Here’s how a functional component would look without destructuring :
const Listing = (props) => (
<div>
<p>Title: {props.listing.title}</p>
<p>Type: {props.listing.type}</p>
<p>
Location: {props.listing.location.city},
{props.listing.location.state},
{props.listing.location.country}
</p>
</div>
);
This block of code is fully functional but looks terrible! By the time we get to this Listing
child component, we already know we’re referencing to a listing
prop, so props.listing
looks and feels redundant. This block of code can be made to look much cleaner through destructuring.
We can achieve this in the function parameter as we pass in the props argument:
const Listing = ({ listing }) => (
<div>
<p>Title: {listing.title}</p>
<p>Type: {listing.type}</p>
<p>
Location: {listing.location.city},
{listing.location.state},
{listing.location.country}
</p>
</div>
);
The reason for ({ listing }) i.e. wrapping listing
in a parentheis – I am passing the listing
prop which is an object (being extracted from the Parent compoenet Property’s properties
array) – And when returning an Object, I will have to wrap it in parentheses. Hence the parenthesis before the curly braces. Just like in a mapStateToProps
function.
Even better, we can further destructure nested objects like below:
const Listing = ({
listing: {
title,
type,
location: {
city,
state,
country
}
}
}) => (
<div>
<p>Title: {title}</p>
<p>Type: {type}</p>
<p>Location: {city}, {state}, {country}</p>
</div>
);
Can you see how much easier this is to read? In this example, we’ve destructured both listings and the keys inside listing.
Properties
component to child Listing
component
Class Child Component implementation passing down the props from above parent Listing
is a class component as a child of Properties
component
That is the case, when The idea is very much the same in class components, only here, I have to use render() and return() syntax while declaring the de-structured listing
prop inside the render()
. Also, I can destructure the Component object as I import React in class components. This isn’t necessary for functional components as we won’t be extending the Component class for those.
import React, { Component } from 'react';
class Listing extends Component {
render() {
const {
listing: {
title,
type,
location: {
city,
state,
country
}
}
} = this.props;
return (
<div>
<p>Title: {title}</p>
<p>Type: {type}</p>
<p>
Location: {city}, {state}, {country}
</p>
</div>
)
}
}
Differences with Functional Component – Instead of destructuring in the argument ( like I did in the functional ), I destructure wherever the variables are being called. For example, here in Listing
child component I destructured in the render()
function where the props are being referenced.