Destructing [] vs {}

Viewed 123

I am confused between destructing.
I am using React in it we do

const [ books, setBooks ] = useState([{a:'v'}]

and

const {books} = useContext(BookContext)

So why cant i

const [books] = useContext(BookContext) // or
const { books, setBooks } = useState([{a:'v'}]

Because both return values and we are destructing them ? How is one different from other ?

5 Answers

To understand this, let's dive into how arrays and objects destructing work.

Assume we have two functions returnsArray() and returnsObject() which returns ['item 1', 'item 2', 'item 3'] and { a: 'Item 1', b: 'Item 2', c: 'Item 3' } resp.

 

How can we extract values from the returnsArray() which returns ['item 1', 'item 2', 'item 3']?

  1. Without destructing:
const tempArray = returnsArray();

const variable1 = tempArray[0]; // Will be 'item 1'
const variable2 = tempArray[1]; // Will be 'item 2'
...
  1. With destructing:
const [variable1, variable2] = returnsArray();

You can clearly observe that destructing reduces the number of lines and makes the code more legible.

Note that the variable1 and variable2 are the custom variable names.

How can we extract values from the returnsObject() which returns { a: 'Item 1', b: 'Item 2', c: 'Item 3' }?

  1. Without destructing:
const tempObject = returnsObject();

const attribute1 = tempObject.a; // which is equal to 'Item 1'
const attribute2 = tempObject.b; // which is equal to 'Item 2'
...
  1. With destructing:
const { a, b } = returnsObject(); // if you want to the variable names as 'a' and 'b' or

const { a: attribute1 , b: attribute2 } = returnsObject(); // if you want to give custom 
// variable names for the attributes 'a' and 'b'

You can clearly see that destructing reduces a lot of unwanted code and makes it more legible.

Now let's look at what will happen when we interchange both?

const [variable1, variable2] = returnsObject();

// above line literally translates to:
const tempObject = returnsObject();

const variable1 = tempObject[0]; // will be undefined
const variable2 = tempObject[1]; // will be undefined

Since we can not access the object's attributes by tempObject[0] & tempObject[1], both the variable values will be undefined.

Similarly,

const { variable1 , variable2 } = returnsArray();

// above line literally translates to:
const tempArray = returnsArray();

const variable1 = tempArray.variable1; // will be undefined
const variable2 = tempArray.variable2; // will be undefined

since tempArray doesn't have any attributes named variable1 & variable2. Both of those values will be undefined.

In your case, returnsArray() is useState() and returnsObject() is useContext().

Mozilla org destructuring hacks

lhs type = rha type

What I mean from above is const [a, b, c] = [some array]; const {a, b, c} = {some object};

And not the other way round object properties can be destructured only by {} and array properties by []

useState returns a tuple i.e. an array like structure with different types of values. More reading on tuples

const [a, b] = ["some string", 2]
// a = "some string", b = 2

useContext returns an object.

Main reason is because Array are sorted and objects are not.

When you destruct result of React.useState(5); you actually destruct value that looks like [5, x => value = x] (it does much more actually but for purpose of this answer let's assume it looks like this). Keys of this array are 0 and 1 (array[0] === 5 (array[1](2), array[0] === 2)). So if use want to use object destructing on this value it'd look like const { 0, 1 } = React.useState(5) but you can't create variable in JavaScript which name starts with or is number.

When you try to destruct object { language: 'JavaScript', age: 25 } you don't know which property goes first. The one which is declared first (language) or maybe the one what is alphabetically first (age)? So you can't expect from language to deduct which value you think should be first.

Descruct with [] when operating on an array, use {} to destruct when operating on an object:

const arr = [10, 20, 30, 40, 50];
const [ a, b, c ] = arr; 

// a is 10
// b is 20
// c is 30

const obj = { foo: "hello", bar: "world" };
const { foo, bar } = obj;

// foo is "hello"
// bar is "world"

Related