React 101

...in 20 minutes

Me and React

  • I've been getting to know it for 1+ year now
  • We are adopting it at work with great success
  • It has had a tremendous impact on me
    • My development skills
    • My career
    • My life and family

Companies Using Contributing to Loving React

You and React

  • Exposure to many *new technologies/concepts
    • ES6+
    • Functional programming
    • *Javascript
  • A paradigm shift that sticks with you and transforms how you approach even non-React/JS projects
  • Career Opportunities (💰💰💰)

It's not always about the money...

But sometimes... it's about the money

What is React?

React is a Javascript Library for Building User Interfaces

What isn't React?

  • It is NOT "MVC"
  • It is NOT "Batteries Included"
  • It is NOT a "Framework"
React is a Javascript Library for Building User Interfaces

React !== React

  • An entire ecosystem of concepts and libraries.
    • GraphQL, Relay, Redux, etc...
  • Accompanying tooling, setup, and config
  • Hot Reloading
  • Flux, Redux, MobX, [INSERT PREFERRED FLAVOR]
React is a Javascript Library for Building User Interfaces

Hello World





/**
 * https://npmcdn.com/react@15.0.1/dist/react.js
 * https://npmcdn.com/react-dom@15.0.1/dist/react-dom.js
 */

ReactDOM.render(
  React.createElement('h1', null, 'Hello World!'),
  document.getElementById('app')
)

Literally: Hello World Codepen

Components

React is all about components.

A component is essentially a description of a piece of user interface.


These are composed together to form an application.



Think... Legos :)

Components

Components all the way down

Components are composed of components are composed of components.

React.createElement(
  'button', // 1st arg is type (string for DOM OR custom component)
  {className: 'btn btn-md btn-primary', someProp: '2nd arg is props!'},
  '3rd argument is the "props.children"'
)

React.createElement('div', null,
  React.createElement('div', null,
    React.createElement('div', null,
      'Components inside of components inside of components'
    )
  )
)

*State

A component is a pure function of *state.

*state in, UI out.

Lifecycle

A component’s behavior is defined by its lifecycle methods.

*state being the combination of both this.state and this.props.

Stateless Function Components

The majority of components can be described, simply, as a pure function of props.

This is the "simplified" API which is the preferred method of defining Components.

No state. No Lifecycle.

/**
 * See: http://facebook.github.io/react/docs/reusable-components.html#stateless-functions
 */
const SomeStatelessComponent = (props) => {
  return (
    <div>
      <h1>Hello, I am SomeStatelessComponent!</h1>
      <h3>{props.message}</h3>
      // Only render children when we are not loading
      {props.loading ? 'Loading...' : props.children}
    </div>
  )
};

Class Components

  • Persist/Manage state
  • Component lifecycle API
  • Refs (to do DOM things)
  • Things SFCs just don’t support.

Props + State + Lifecycle

/** See http://facebook.github.io/react/docs/component-specs.html */
const SomeStatefulComponent = React.createClass({
  // Define the initial "state" of our component
  getInitialState() {
    // state is updated via this.setState({loading: true})
    return {loading: false}
  },

  render() {
    // Here, we have access to this.props as well as this.state
    return (
      <div>
        <h1>Hello, I am SomeStatefulComponent!</h1>
        <h3>{this.props.message}</h3>
        // Only render children when we are not loading
        {this.state.loading ? 'Loading...' : this.props.children}
      </div>
    )
  }
});

+ More...

PropTypes

import React, {PropTypes} from 'react'

const examplePropTypes = {
  // Require the title
  title: PropTypes.string.isRequired,
  // Optional function
  doThisWhenClicked: PropTypes.func,
  // Some array of "special things with a certain shape"
  specialThings: PropTypes.arrayOf(
    PropTypes.shape({
      id: PropTypes.number.isRequired,
      name: PropTypes.string.isRequired,
      deleteMe: PropTypes.func.isRequired,
      specialOptionalAttribute: PropTypes.any,
      tags: PropTypes.arrayOf(PropTypes.string),
    })
  ).isRequired,
}

const MyComponent = (props) => {/*...*/}
MyComponent.propTypes = examplePropTypes

const MyComponent = React.createClass({
  propTypes: examplePropTypes,
  // ...
})

class MyComponent extends React.Component {/*...*/}
MyComponent.propTypes = examplePropTypes

An API to declare and validate props. 

A component's propTypes are essentially its way of saying “if you are going to use me, this is what I need”.

Helpful console warnings + Great when visiting a component that you did not author (or after 6 months)

JSX

Would you like some sugar with your function calls?

But it's scary

Fear not!

It is nothing more than syntactical sugar on top of the Javascript function calls you already know and love.

import React from 'react';

const Header = ({title, subtitle}) => (
  <section className="hero">
    <h1 className="title">
      {title}
    </h1>
    <h2 className="subtitle">
      {subtitle}
    </h2>
  </section>
);

All 3 examples are equivalent

  1.   With JSX
  2.   Without
  3.   Without (DOM helpers)

It may look like

  • Writing HTML inside of JS (it is not)
  • Some new templating language (it is not)
import { createElement as el } from 'react';

const HeaderWithoutJsx = ({title, subtitle}) => (
  el('section', {className: 'hero'},
    el('h1', {className: 'title'},
      title
    ),
    el('h2', {className: 'subtitle'},
      subtitle + ' Without JSX'
    )
  )
);
import { DOM } from 'react';
const {section, div, h1, h2} = DOM;

const HeaderWithDomHelpers = ({title, subtitle}) => (
  section({className: 'hero'},
    h1({className: 'title'},
      title
    ),
    h2({className: 'subtitle'},
      subtitle + ' Without JSX (using DOM helpers)'
    )
  )
);

Two Way Data Binding

Look into the light

Querying DOM Values

...you know what to do

One Way Data Flow

Data Flow

  • Parents (higher up in the hierarchy) pass props down to their children.
  • Some props represent “a piece of state” (read)
  • Some props are functions that "update/affect state higher up the chain” (write)

In React, all data flows from the top to the bottom.


/**
 * The parent "owns" and manages the state.
 * It passes down props to its children
 *  Some props are data and the children simply display them "read"
 *  Some props are functions that can update/affect state "write"
 */
const ShoppingCart = React.createClass({
  getInitialState() {
    return {
      cartQuantity: 0,
    };
  },
  
  incrementQuantity() {
    this.setState({
      cartQuantity: this.state.cartQuantity + 1,
    });
  },
  
  render() {
    const { cartQuantity } = this.state;
    return (
      <div>
        <h3>A Great Item</h3>
        <QuantityDisplayer quanity={cartQuantity} />
        <MoarButton increment={this.incrementQuantity} />
      </div>  
    )
  }
});

/**
 * The children require/accept props from "the great above" (parent)
 */
  
const QuantityDisplayer = (props) => (
  <div>
    Quantity in cart: {props.quantity}
  </div>
);

QuantityDisplayer.propTypes = {
  quantity: React.PropTypes.number.isRequired,
};

const MoarButton = (props) => (
  <button onClick={props.increment}>
    MOAR!!!
  </button>
);

MoarButton.propTypes = {
  increment: React.PropTypes.func.isRequired,
};

"Controlled" Components

A Controlled component does not maintain its own internal state; the component renders purely based on props.

Example!

/** A Form w/ a "controlled" component (input) */
const SomeForm = React.createClass({
  getInitialState() {
    return {firstName: ''}
  },
  
  handleChangeFirstName(event) {
    this.setState({
      firstName: event.target.value
    })
  },
  
  handleSubmit(event) {
    event.preventDefault()
    alert(`First Name: ${this.state.firstName}!`)
  },
  
  render() {
    const {firstName} = this.state
    
    return (
      <div>
        <h3>A Great Form</h3>
        <form onSubmit={this.handleSubmit}>
          First Name <input 
            type="text"
            value={firstName}
            onChange={this.handleChangeFirstName}
          />
          <button>Submit</button>
        </form>
      </div>
    )
  }
})

input simply renders the value that is given. The DOM event is handled by handleChangeFirstName and the new value trickles back down.

Enough. Enough!

Recap

  • It may be a worthwhile investment of time/energy to at least spend a week or so playing with React
  • React is a Javascript Library for Building User Interfaces
  • React is not MVC, a framework, or a complete solution
  • Less opinionated, so more decisions
  • Smaller/simpler, so must be augmented by other libraries
  • Do not fear the JSX!
  • One Way Data Flow
    • Forget two way data binding and DOM querying
  • Components all the way down
    • Stateless Function Components
    • Class Components
    • PropTypes
    • Controlled Components

Where to Start?

React 101: The Condensed Version - Erik Aybar

Made with Slides.com