Day 6: React

Tuesday, May 22, 2018

Recap

Lecture Videos

Morning:

Afternoon:

Topics

Scope

  • Variable Scope (var, const, let)

React

Examples

Variable Scope

The biggest difference between var and let is that var variables are scoped to the function in which they are declared, while let variables are scoped to the block in which they are declared. One of the easiest examples to see this behavior is in a simple for loop.



function loopStuff() {
  for (var i = 0; i < 5; i++) {
    // do stuff in the loop
  }
  console.log(i)
}

loopStuff() // => 5

function loopMoreStuff() {
  for (let i = 0; i < 5; i++) {
    // do stuff in the loop
  }
  console.log(i)
}

loopMoreStuff() // => Uncaught ReferenceError: i is not defined


In the function loopStuff, var i is still available outside the for loop so it can be logged to the console. It is scoped to the function itself.

In the function loopMoreStuff, let i is not available outside the block it is scoped to (the for loop).

The main difference between const and var/let is that const cannot be reassigned.



let variableOne = 4
variableOne = 5

var variableTwo = 4
variableTwo = 5

const variableThree = 4
variableThree = 5 // => Uncaught TypeError: Assignment to constant variable


Default to using const

Always use const as your default way to declare variables, unless you know specifically that you will need to reassign it, in which case use let. You should rarely, if ever, use var. For further reading, check out this article.

React

Using map with Components

Person.js



class Person extends React.Component {
  render() {
    return (
      <li>Hello, {this.props.person.name}!</li>
    )
  }
}

export default Person


PersonList.js



import Person from './Person'

class PersonList extends React.Component {
  render() {
    const people = [
      { name: 'Dana', hair: 'blonde' },
      { name: 'Nichole', hair: 'long' },
      { name: 'Davey', hair: 'long gone' }
    ]
    return (
      <div>
        <h2>People</h2>
        {
          people.map((person => <Person person={person} />))
        }
      </div>
    )
  }
}

export default PersonList


Stateless Functional Components

Not every React Component needs to have state. Many simply render a bit of props and UI. For such components, we don’t need to instantiate a whole class that inherits from React.Component, we can simply write a function that accepts props as an argument and returns the markup we need.

For instance, in the previous example, the Person component can easily be re-written as a Stateless Functional Component.



function Person (props) {
  return (
    <li>Hello, {props.person.name}!</li>
  )
}

// Or...

const Person = (props) => <li>Hello, {props.person.name}!</li>


JavaScript (ES6+)

Named and default exports and imports

Prior to ES6, there were many competing ways to export and import JavaScript modules. The most common were CommonJS and AMD. Luckily ES6 defined a specification for standardizing module export and import.

There are two types of exports from any JS file - named and default. The important thing to remember is that there can only be one default export per module, but there can be as many named exports as you want.

myModule.js



export const myNumber = 8

export function sayHi () {
  console.log('hello')
}

export default class MyClass {
  add (a, b) {
    return a + b
  }
}


The main difference is how they are imported. Default exports get the most concise syntax:



import MyClass from 'myModule'

const classInstance = new MyClass()
classInstance.add(1, 2) // => 3


Default import naming

Since there can be only one default export per module, the name by which you import the default export is not important - you can name it whatever you want. For instance, instead of importing as MyClass, we could have said import LuftBallons from 'myModule', and it would have worked just fine. To read more about default and named exports, click here.

Named exports get a slightly more verbose syntax for importing, and the names are important (otherwise it can’t determine what you want to import).



import { myNumber, sayHi } from 'myModule'

console.log(myNumber) // => 8

sayHi() // => 'hello'


If you need to import a named export under a different name—if, for example, you have another import or local variable with the same name—you can specifiy a different name using as.



import { myNumber as num, sayHi as yo } from 'myModule'

console.log(num) // => 8

yo() // => 'hello'


You can also combine default and named imports in the same line.



import MyClass, { myNumber, sayHi } from 'myModule'


Projects

Homework

  • Finish styling Sidebar.
  • Add JSX and style to NoteList and NoteForm.

Bonus Credit

  • Store a list of hard-coded notes in state.
  • Use map to list these notes in NoteList.

Super Mega Bonus Credit

Load a note into NoteForm when you click it in NoteList.