4

I've used const { ... } to do object destructuring in Javascript, but I've seen some recent examples with const [ ... ] doing array destructuring more recently.

For example, from the React Hooks documentation:

const [state, setState] = useState(() => {
  const initialState = someExpensiveComputation(props);
  return initialState;
});

Why would array destructuring be used or preferable in a case like this? In other words, why did they design the useState function to return a pair of results as an array, instead of returning an object?

It seems like the benefit of object destructuring is that it's named, more familiar, and order independent.

Javid Jamae
  • 8,741
  • 4
  • 47
  • 62

3 Answers3

1

So you can call the variables whatever you want

const [bananas, setBananas] = useState(...)

if it were like this:

const {bananas, setBananas} = useState(...)

then useState would need to return:

{
   bananas: (...),
   setBananas: (...)
}

And every developer who wants to useState would need to have a variable named bananas or else alias it to something else which is way more complicated than just returning an array instead

Carlos Sá
  • 602
  • 3
  • 10
  • "*So you can call the variables whatever you want*" – You can do that with an object, too: `const {state: bananas, setState: setBananas} = useState(...)`. – str Aug 23 '19 at 16:51
  • But you would need the name of the properties returned and you would need more code to alias it – Carlos Sá Aug 23 '19 at 17:12
  • @str Yes, you can, but a) it's overly verbose and b) it does tempt users not to alias the properties and go with non-descriptive variable names instead. – Bergi Aug 23 '19 at 18:14
-1

You can have multiple states in a component.

When you return an object, you almost always need to alias the state & setState.

function App() {
  const {state: age, setState: setAge} = useState(0);
  const {state: name, setState: setName} = useState('');
}

Returning an array, let you simply name the returned state & setState.

And the name state and setState is too generic to be useful in many cases.

But when you write your own custom hooks returning states/updator/dispatcher, it'd make more sense to return an object in many cases.

dance2die
  • 35,807
  • 39
  • 131
  • 194
-1

What you consider as an array is actually meant to be a tuple. JavaScript doesn't have an extra data type for them, but its heterogeneous arrays work well. As you said, it's a pair of results, not an array.

Why would one prefer to return a pair of results as an array, instead of returning an object?

Because of its simplicity. You don't need to declare some verbose type (assuming TypeScript) and come up with names for the properties. It's not a StateUse<S> { state: S, setState: S => S } result, it's a simple Tuple<S, S=>S> or [S, S=>S] (depending on what syntax you prefer).

It's exactly the same reasoning why we use functions with multiple parameters instead of a parameter object when there are only a few parameters, just applied the output type instead of the input type.

It seems like the benefit of object destructuring is that it's named, more familiar, and order independent.

Array destructuring is is even simpler than object destructuring, and should be familiar as well. When dealing with only two result values and never changing that, a tuple is just simpler. It is expected that one would never need to add another property (in that case the object would be superior). Not having property names makes it easier (less verbose) to use aliases as the destructuring targets. It forces the user to come up with a good, appropriately descriptive variable name himself.

That it relies on an order doesn't matter, the order just follows conventions like [getter, setter] or [key, value], and you typically always want to use both values so there's no benefit in being able to omit a property from destructuring.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375