Day 7: Props and Destructuring

Thursday, July 6, 2017

Lecture Videos

Morning: Day 7, part 1

Afternoon: Day 7, part 1

Topics

React

JavaScript

  • Destructuring assignment
  • Spread operator
  • Property initializers (and arrow functions)

Firebase

  • Getting started
  • Re-base for syncing React state with Firebase

Examples

React

Methods as props

Sometimes one component needs to update another component’s state. It can’t do that directly, but it can call a method from that other component if it’s available via a prop.

Try this example live on CodePen


  
import React from 'react'
import ReactDOM from 'react-dom'

const PartyButton = ({ celebrate, celebrations }) => {
  return <button onClick={celebrate}>Party! {celebrations}</button>
}

class App extends React.Component {
  constructor() {
    super()
    this.state = {
      celebrations: 0,
    }
    this.celebrate = this.celebrate.bind(this)
  }

  celebrate() {
    const celebrations = this.state.celebrations + 1
    this.setState({ celebrations })
  }

  render() {
    return <PartyButton celebrate={this.celebrate} celebrations={this.state.celebrations} />
  }
}

ReactDOM.render(<App />, document.querySelector('main'))

  
  

Component lifecycle methods

componentDidMount() is invoked immediately after a component is mounted. Initialization that requires DOM nodes should go here.



import React, { Component } from 'react'

class MyComponent extends Component {
  componentDidMount() {
    this.nameInput.focus()
  }

  render() {
    return (
      <input 
        ref={(input) => { this.nameInput = input; }} 
        defaultValue="will focus"
      />
    )
  }
}


JavaScript (ES6+)

Destructuring assignment

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



const myObj = {
  a: true,
  b: 'Destructuring!'
}

let { a, b } = myObj

console.log(a) // => true
console.log(b) // => 'Destructuring!'


Spread operator

The spread operator was added in ES6 to allow an expression to be expanded in places where multiple arguments (for function calls) or multiple elements (for array literals) or multiple variables (for destructuring assignment) are expected.



function myFunc (x, y, z) {
  console.log(x)
  console.log(y)
  console.log(z)
}
const args = [1, 2, 3]

myFunc(...args) // the spread '...args' applies the items in args to the three arguments in myFunc
// => 1
// => 2
// => 3


It is also an easy way to make copies of iterable objects



const ary = [1, 2, 3]
const aryCopy = [...ary] // makes a copy of ary


If you are in a project using Babel (like a React project created with create-react-app), you can also use the object-rest-spread-transform to apply this same method to objects.



this.state = {'a': true, party: 'hard'}
const stateCopy = {...this.state} // makes a copy of this.state


Property initializers

From the proposal:

“Class instance fields” describe properties intended to exist on instances of a class (and may optionally include initializer expressions for said properties).

We can take advantage of this in React.

Read more: Using ES7 property initializers in React

We can use a property initializer to set the initial value of state without writing a constructor:



class Song extends React.Component {
  state = {
    versesRemaining: 5,
  }
}


We can even set default props and use those in the initial state:



class Song extends React.Component {
  static defaultProps = {
    autoPlay: false,
    verseCount: 10,
  }
  state = {
    versesRemaining: this.props.verseCount,
  }
}


Subject to minor changes

Property initializers are a Stage 2 proposal for ECMAScript, meaning that it’s still a draft and is subject to minor changes before becoming standardized. Facebook itself is already using these techniques in production, however.

Property initializers + arrow functions

Combining property initializers and arrow functions gives us a convenient way to auto-bind this, since arrow functions inherit this from the scope in which they are declared (lexical scoping):



class Something extends React.Component {
  handleButtonClick = (ev) => {
    // `this` is bound correctly!
    this.setState({ buttonWasClicked: true });
  }
}


Firebase

Getting Started

Firebase is a real-time database hosted by Google. In addition to the database, it also provides features of authentication, analytics, cloud storage, and hosting. For Noteherder, we synced the state of our app to our database on Firebase. This allowed all of our data to be persisted, even after page refreshes.

Re-base is an open source package that allows easy syncing of local state with a Firebase database. Add rebase to your project with one of the following commands:

user@localhost ~
 
yarn add re-base               # add package using yarn
npm install re-base            # add package using npm

Once you have re-base installed, setup is easy! First, create a new project on Firebase, then click on “Add to a web app” to see your JavaScript config object. Next, initialize a Firebase app and database in your project using the config object, and provide the database to re-base.



import Rebase from 're-base'
import firebase from 'firebase/app'
import database from 'firebase/database'

const app = firebase.initializeApp({
  apiKey: "YOURAPIKEY",
  authDomain: "YOURAUTHDOMAIN",
  databaseURL: "YOURDATABASEURL",
  projectId: "YOURPROJECTID",
  storageBucket: "YOURSTORAGEBUCKET",
  messagingSenderId: "YOURSENDERID"
})

const db = database(app)
const base = Rebase.createClass(db)

export default base


Finally, call base.syncState to sync your app’s local state with Firebase. The first argument to syncState is the name of the Firebase endpoint you want to sync, and the second is a configuration object.



base.syncState('myFavoriteEndpoint', {
  context: this,
  state: 'items'
})


Now, any time we update the state of our app, the changes will sync with Firebase in real time.

More Re-base Options

Re-base can do much more than just syncing state. There are methods for fetch, push, post, etc. To find out more about what all you can do with re-base, check out the README

Projects

Homework

Practice!

  • Finish any levels of homework for the week that are not yet complete.
  • Re-watch any lecture videos about concepts you are not 100% clear on.
  • Try out the React tutorial at https://reacttraining.com/.