Skip to content

Instantly share code, notes, and snippets.

@antonioOrtiz
Last active June 16, 2020 21:21
Show Gist options
  • Save antonioOrtiz/3543bb81cb03bb428aa3258a99edaa53 to your computer and use it in GitHub Desktop.
Save antonioOrtiz/3543bb81cb03bb428aa3258a99edaa53 to your computer and use it in GitHub Desktop.

Prerequisities

Knowledge of foundational JS knowledge including:

  • variables, conditionals, arrays & objects classes

Related React knowledge includes:

  • how to create a component that returns an element

  • how to import modules into a file,

  • how props are passed from component to component, component lifecycles.

You may have heard the following many, many, many times,

"One of the best things about React is this—"It's just JavaScript!!!""

I know you're probably saying what does that even mean? And why do people keep saying that? I wish people would just tell me why? Kinda like "Walking in nature is good for you!" Please explain the "good" in that sentence!?

React aims to focus on the API's so you can focus on creating your application or website.

Briefly, in other libraries or frameworks there are abstractions e.g. syntax, coventions, which only exist in their contexts. Meaning the framework itself created it and doesn't exist outside of it i.e. Vanilla JavaScript.

For example from the Angular Docs (GETTING STARTED > Try it > A Sample App), consider the following:

<h2>Products</h2>

<div *ngFor="let product of products">

  <h3>
      {{ product.name }}
  </h3>

</div>

As you know, one of the attributes of JavaScript Arrays and Objects is the can hold data. So it's probably not a leap to intuiate—because of the ngFor syntax above, Angular is providing a convention to interate through some data. In this case some products.

From the docs:

With *ngFor, the <div> repeats for each product in the list.

*ngFor is a "structural directive". Structural directives shape or reshape the DOM's structure, typically by adding, removing, and manipulating the elements to which they are attached. Directives with an asterisk, *, are structural directives.

So you can think of it like:

The data:

var products = [
  {
    name : 'headphones',
  },
  {
    name : 'laptop',
  },
  {
    name : 'monitor',
  },
]

And Angular code is essentially doing something like this:

for (var i = 0; i < products.length; i++) {
  console.log(products[i].name)
}

headphones
laptop
monitor

But with a big difference, the snippet using the for loop here is considering the console or REPL, which is going to be the environment where a user or consumer views the data; While the Angular code is considering a HTML template to house what the user sees from the DOM.

One could easily imagine using the for loop, but immediatley—If you've ever had to write a JavaScript to manipulate the DOM. You'll remember, there is a little preamble you'd have to get through first:

You would have to create a script file or embed a script into the markup, create a way for the script to interact with the DOM i.e. a selector of some kind and finally, to be considerate to your future and more elderly self, both script and HTML files will have some comments and have clear file structure for future updates.

The Angular code has created a construct within the template to abstract all that away!

Okay, before we get into destructuring with React, let's find out a little about destructuring itself!

Destructuring was introduced in the 7th Edition of ECMAScript 2016 standard.

And accoriding to the MDN web docs about destructuring:

The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.

With that knowledge; Let's say you had an object assigned to a variable:

  var starShip = {
    name: 'Enterprise',
    registry: 1701,
    sovereignty: 'Federation',
  };

And you wanted to use a property of that object in a operation of somekind elsewhere, You'd have to do something like this:

  if (starShip.sovereignty === 'Federation') {
    hailingFunction('peaceful')
  }

Or if you wanted to assign it to a variable, you'd do this:

  var registry = starShip.registry;

With the following expression, you can just use it without the starShip identifier:

  var { registry } = starShip; 

    `What is the registry of that ship helmsman?` // Klingon captain,
    `${registry}, Sir!` //Klingon helmsman,  outputs: 1701, Sir!

So essentially you create a new variable with the exact property name from the object you want:

For example this won't work:

  var { starShipName, registryName, alliegence } = starShip;

That operation will yield three new variables with undefined.

However this will work:

  var { name: starShipName, registry: registryName } = starShip;

And in Arrays, instead of doing this:

  var laptops = ['macbook-air', 'Chromebook', 'microsoft-laptop'];

  var macBookAir = laptops[0];
  var chromeLaptop = laptops[1];
  var microSoftlaptop = laptops[2];

You can could destructure the value from the Array like so:

  var [ macBookAir, chromeLaptop, microSoftlaptop ] =  laptops;

So macBookAir has been assigned the value from the first index in the laptops array which was macbook-air, chromeLaptop has the value of Chromebook and microSoftlaptop has been assigned the string microsoft-laptop.

You're probably thinking "Um, isn't this about destructuring in React???" Okay here we go!!!

In React we make Components which can either be a function or a class, which can optionaly accept an input and returns a element.

We are going to focus on the how inputs are consumed by our Components particualy how destructuring really makes the declaritive nature of React shine! And because this module is about destructuring! \o/

Once we have data from a source, i.e. a database, API, store of somekind etc. We want the data to be easier to reason about.

So when our future and more elderly self returns or perhaps for another developer works with the code source they understand things quicker.

So we know props in React is an object it gives us to manipulate data it receives to then use like HTML attrbutes e.g. <input type="file"/>; Consider the following:

class DesktopContainer extends Component {
  render() {
    const {
      navData,
    } = this.props;
    
    return (
     
    )
  }
}

Which means this Component e.g. DesktopContainer has a property called navData which is being assigned to the props:

class App extends Component {
  let navBars = [
    { name: 'Home', path: '/' },
    { name: 'Profile', path: '/profile' },
    { name: 'Dashboard', path: '/dashboard' },
    { name: 'Log in', path: '/login' },
    { name: 'Register', path: '/register' }
   ];

 render(){
  return (
    <DesktopContainer navData={navBars} />
  )
 }
}

Which we could think of like this:

  DesktopContainer.props = {} //React Object

  DesktopContainer.props = {
    navData : [
      { name: 'Home', path: '/' },
      { name: 'Profile', path: '/profile' },
      { name: 'Dashboard', path: '/dashboard' },
      { name: 'Log in', path: '/login' },
      { name: 'Register', path: '/register' }
   ];
  }

  DesktopContainer.props[navData] = navBars;

So if that's the case, How would you create a navigation bar for this DesktopContainer Container utilizing destructing?

  • For the sake of simplicity you we have created a MenuItem for you to utilize

• MenuItem has two props of it's own LinkName and LinkPath

import MenuItem from './MenuItem'

class DesktopContainer extends Component {
  render() {
    const { } = this.props;
    
    return (
     
    )
  }
}

For extra credit how would it look like if it was a Function Component in React?

Solution
import MenuItem from './MenuItem'

class DesktopContainer extends Component {
  render() {
    const {
      navData,
    } = this.props;
    
    return (
      <>
        navData.map(nav => {
        var { name, path } = nav;
          return (
            <MenuItem
             key={name}
             LinkPath={path}
             LinkName={name}
            />
          )
        })
      </>
    )
  }
}

// Functional Component

function DesktopContainer({navData}){
  return (
    <>
      navData.map(nav => {
        var { name, path } = nav;
          return (
            <MenuItem
             key={name}
             LinkPath={path}
             LinkName={name}
            />
          )
        })
      </>
    )

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment