1

I have this code in a friend of mine React application and I need to understand what this code does explicitly:

const Component = ()=> (
  <QueryFetcher>
    {({ data }) => {

      const { user: { profile = {} } = {} } = data

      return (
        <div>
          {profile.username && profile.username}
        </div>
      )
    }}
  </QueryFetcher>
)

What is this line for?

const { user: { profile = {} } = {} } = data

Is it correct to assign something to {} using { user: { profile = {} } = {} } in this functional component? Or in a render() hook of a stateful component in React?

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Fred Hors
  • 3,258
  • 3
  • 25
  • 71
  • 1
    This is the ES6 destructuring syntax. – Emile Bergeron Apr 30 '19 at 20:30
  • 1
    Possible duplicate of [What does curly brackets in the \`var { ... } = ...\` statements do?](https://stackoverflow.com/questions/15290981/what-does-curly-brackets-in-the-var-statements-do) – Emile Bergeron Apr 30 '19 at 20:34
  • 2
    It's roughly equivalent to `const profile = (data && data.user && data.user.profile) || {}` – p.s.w.g Apr 30 '19 at 20:36
  • 1
    Note that `{profile.username && profile.username}` is redundant, as `{profile.username}` should be enough. – Emile Bergeron Apr 30 '19 at 20:42
  • 1
    Note that if `data` is `{ user: null }`, the destructuring would still fail even with the default values in place. That's something that the answers below are not mentioning and that is a huge source of uncaught errors. – Emile Bergeron Apr 30 '19 at 20:54
  • See this [MDN doc](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Default_values_2) – jo_va Apr 30 '19 at 20:58
  • @p.s.w.g, is this correct to use this syntax in a render() hook in React? – Fred Hors Apr 30 '19 at 21:13
  • @EmileBergeron, is this correct to use this syntax in a render() hook in React? – Fred Hors Apr 30 '19 at 21:13
  • There's nothing wrong with it *per se*, though I personally find this syntax a bit harder to read than the plain old `foo && foo.bar && ...` kind of afe property accessor. Even better, you could use [`lodash.get`](https://lodash.com/docs/4.17.11#get), e.g. `const profile = _.get(data, 'user.profile');` – p.s.w.g Apr 30 '19 at 21:20
  • It's unrelated to react. – Emile Bergeron Apr 30 '19 at 21:23

2 Answers2

4

const { user: { profile = {} } = {} } = data basically means that your retrieving the user profile.

const means that you are creating a new variable

{ user: { profile } } } means that you are retrieving profile inside of user

= {} means that if the object is undefined, use an empty object so it will not fail because doing user.profile will throw an error if user is undefined.

= data means that you retrieving this info from the data variable

So, this line means, from the variable data, go take the user, if the user is undefined, use an empty object. Then, go take the profile, if the profile is undefined, use an empty object. Then create a variable called profile with the result. This is like doing this:

const user = data.user === undefined ? {} : data.user;
const profile = user.profile === undefined ? {} : user.profile;
Vincent D'amour
  • 3,746
  • 1
  • 27
  • 39
3

What is this line for?

const { user: { profile = {} } = {} } = data

It's basically just chained ES6 object-destructuring with default values. What this line does in words:

  1. Read "user" from "data", if "user" is undefined, assign {} as a default value
  2. Read "profile" from "user", if "profile" is undefined, assign {} as a default value

Is it correct

It is mostly a short-hand syntax used to remove repetitive stuff. So instead of accessing multiple object props separately e.g.

this.props.prop1, this.props.prop2, ...

you can use

const { prop1, prop2 } = this.props;

It also helps other readers later quickly understanding what variables are used in a method if all necessary props are destructured at the start.

Berouminum
  • 500
  • 4
  • 7
  • 1
    _"if [whatever] is falsy"_, not _falsy_, specifically `undefined` and it's a huge source of uncaught errors. – Emile Bergeron Apr 30 '19 at 20:45
  • Thanks, but is this correct to use this syntax in a render() hook in React? – Fred Hors Apr 30 '19 at 21:10
  • @FredHors Sure, you can destructure all needed props in render. I personally wouldn't only call it "correct" but even good-practice regarding the readability advantages i mentioned above. – Berouminum Apr 30 '19 at 21:15