Slide 1

Slide 1 text

REACT GETTING INTO JAKE TRENT

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

REACT IS A: npm install react ▸ Let the fun begin! UI LIBRARY

Slide 5

Slide 5 text

INSIDE A: COMPONENT

Slide 6

Slide 6 text

UI ABSTRACTION: COMPONENTS ▸ Exposes a React.Component import React from ‘react’

Slide 7

Slide 7 text

COMPONENTS OUTPUT: VIEW ▸ Matches the DOM
For your eyes only

Slide 8

Slide 8 text

REACT APPROACH VIEW ONLY ▸ Just a view ▸ Just a library ▸ Bring your own: app framework, client router, http library, module system, service layer, model library

Slide 9

Slide 9 text

CUSTOM COMPONENTS: ▸ Semantic naming ▸ Capitalized == custom ▸ Composable hierarchy

Slide 10

Slide 10 text

REACT COMPONENTS ARE: ▸ Return DOM function SideNav() { return
...
} JUST FUNCTIONS

Slide 11

Slide 11 text

REACT APPROACH SEPARATION OF CONCERNS ▸ Not technology ▸ Uses JSX (superset of JS) ▸ Include what looks like HTML in your functions function SideNav() { return
...
}

Slide 12

Slide 12 text

COMPONENT STATE: PROPS ▸ Immutable bag of data ▸ Flow into component from parent function SideNav(props) { return
{props.links}
} ▸ Allow dynamic output ▸ Like arguments to a function

Slide 13

Slide 13 text

JSX NOTE: CURLIES
{props.links}
▸ Switch back to JS from HTML ▸ Inside curlies interpreted as {plain JS}

Slide 14

Slide 14 text

COMPONENT STATE: PASS PROPS ▸ Like attributes in HTML

Slide 15

Slide 15 text

TWO STYLES: COMPONENT SYNTAX ▸ Function style (aka “stateless components”) import React from ‘react’ class MyComponent extends React.Component {} ▸ Class style import React from ‘react’ function MyComponent() {}

Slide 16

Slide 16 text

COMPONENT STATE: THIS.STATE ▸ Internal to component ▸ Mutable ▸ Requires class-style components

Slide 17

Slide 17 text

STATE INITIALIZATION: THIS.STATE import React from ‘react’ class Counter extends React.Component { constructor(props) { super(props) this.state = { count: 0 } } }

Slide 18

Slide 18 text

STATE UPDATING: THIS.SETSTATE import React from ‘react’ class Counter extends React.Component { handleCountUpdate() { this.setState({ count: this.state.count + 1 }) } } ▸ (the mutating)

Slide 19

Slide 19 text

COMPONENT: RENDERING

Slide 20

Slide 20 text

COMPONENT CLASS: RENDERING import React from ‘react’ class SideNav extends React.Component { render() { return
{this.props.links}
} } ▸ Note `this.props.links` vs. `props.links` ▸ Must implement `render`

Slide 21

Slide 21 text

COMPONENTS RENDER: VIRTUAL DOM import React from ‘react’ class SideNav extends React.Component { render() { return
{this.props.links}
} } ▸ Return DOM… Virtual DOM

Slide 22

Slide 22 text

VIRTUAL DOM: ▸ In-memory representation ▸ Handled by React ▸ Manages changes, dirty checking ▸ Auto updates the real DOM Real DOM Virtual DOM React-managed Browser-managed

Slide 23

Slide 23 text

JSX TRANSFORMED INTO: FUNCTION CALLS
{props.links}
▸ Before React.createElement(‘div’, props.links) ▸ After

Slide 24

Slide 24 text

IN-MEMORY: DOM REPRESENTATION { '$$typeof': Symbol(react.element), type: 'div', key: null, ref: null, props: { '0': 'home', '1': 'about' }, _owner: null, _store: {} } ▸ Output of `React.createElement`

Slide 25

Slide 25 text

REACT APPROACH NO TEMPLATE LANGUAGE ▸ JSX small differences vs. HTML: ▸ camelCase attributes - e.g., `onClick` (except aria-* & html-*) ▸ html* prefix - e.g., `htmlFor` ▸ alternate words - e.g., `className` ▸ Curlies revert back to {JS}

Slide 26

Slide 26 text

CONNECT REACT TO: REAL DOM npm install react-dom import { render } from ‘react-dom’ render(, document.getElementById(‘app’)) ▸ Call it once ▸ React handles translating VDOM to DOM

Slide 27

Slide 27 text

REACT APPROACH LEARN ONCE, WRITE ANYWHERE ▸ Multiple render targets ▸ react-dom ▸ react-dom/server ▸ react-native

Slide 28

Slide 28 text

INSERTED INTO DOM: “MOUNT” ▸ When your component is inserted into the real DOM ▸ 1. Created in memory ▸ 2. ReactDOM.render ▸ 3. Mount ▸ 4. Eventual removal called “unmount”

Slide 29

Slide 29 text

in DOM / visible COMPONENT MOUNT: Mount Unmount constructor componentWillMount componentDidMount componentWillUnmount ▸ ▸ ▸ ▸ ▸ LIFECYCLE HOOKS time ▸

Slide 30

Slide 30 text

ACCESS TO DOM: REF class UsernameField extends React.Component { render() { return this.input = el} /> } }

Slide 31

Slide 31 text

ACCESS TO DOM: DID MOUNT class UsernameField extends React.Component { componentDidMount() { this.input.focus() } render() { return this.input = i} /> } }

Slide 32

Slide 32 text

HANDLING: EVENTS ▸ camelCase attributes ▸ eg, `onClick`, `onSubmit`, `onChange`, … handleChange(evt) { this.setState({ username: evt.target.value }) }

Slide 33

Slide 33 text

EVENT GOTCHA: CALLBACK BINDING constructor(props) { super(props) this.handleChange = this.handleChange.bind(this) } handleChange(evt) { this.setState({ username: evt.target.value }) } ▸ bind to component context in constructor

Slide 34

Slide 34 text

REAL: COMPONENT class UsernameField extends React.Component { constructor() {…} componentDidMount() {…} handleChange() {…} render() {…} }

Slide 35

Slide 35 text

REAL: COMPONENT class UsernameField extends React.Component { constructor(props) { super(props) this.state = { username: ‘’ } this.handleChange = this.handleChange.bind(this) } componentDidMount() {…} handleChange() {…} render() {…} }

Slide 36

Slide 36 text

REAL: COMPONENT class UsernameField extends React.Component { constructor() {…} componentDidMount() {…} handleChange() {…} render() { return {this.props.label} this.input = el} onChange={this.handleChange} /> } }

Slide 37

Slide 37 text

REAL: COMPONENT class UsernameField extends React.Component { constructor() {…} componentDidMount() { this.input.focus() } handleChange() {…} render() {…} }

Slide 38

Slide 38 text

REAL: COMPONENT class UsernameField extends React.Component { constructor() {…} componentDidMount() {…} handleChange(evt) { this.setState({ username: evt.target.value }) } render() {…} }

Slide 39

Slide 39 text

REAL: COMPONENT class UsernameField extends React.Component { constructor(props) { super(props) this.state = { username: ‘’ } this.handleChange = this.handleChange.bind(this) } componentDidMount() { this.input.focus() } handleChange(evt) { this.setState({ username: evt.target.value }) } render() { return {this.props.label} this.input = el} onChange={this.handleChange} /> } }

Slide 40

Slide 40 text

MULTIPLE: COMPONENTS

Slide 41

Slide 41 text

SHARING: DATA ▸ Lift to common parent ▸ Pass to children as `props` LoginForm UsernameField PasswordField

Slide 42

Slide 42 text

SHARING: DATA LoginForm UsernameField PasswordField this.state = { username: ‘’ password: ‘’ } ▸ Data flows down

Slide 43

Slide 43 text

NOTIFYING: CHANGE ▸ Communicating change to parent ▸ Via callback functions LoginForm UsernameField PasswordField

Slide 44

Slide 44 text

NOTIFYING: CHANGE LoginForm UsernameField PasswordField handleChange(evt) { this.setState({ [evt.target.name]: evt.target.value }) } ▸ Changes notify up

Slide 45

Slide 45 text

REACT APPROACH EXPLICIT FLOW ▸ Strict conventions ▸ props ▸ callbacks ▸ No automatic binding ▸ Explicit plumbing

Slide 46

Slide 46 text

RENDERING: CHANGES ▸ Re-render triggered by changes to: ▸ this.props ▸ this.state ▸ Re-render self and children

Slide 47

Slide 47 text

RENDERING: CHANGES LoginForm UsernameField ▸ Example: User types username

Slide 48

Slide 48 text

RENDERING: CHANGES LoginForm UsernameField User types, triggers props.onChange

Slide 49

Slide 49 text

RENDERING: CHANGES LoginForm UsernameField props.onChange calls back to parent

Slide 50

Slide 50 text

RENDERING: CHANGES LoginForm UsernameField this.handleChange called, this.setState() w/ new value

Slide 51

Slide 51 text

RENDERING: CHANGES LoginForm UsernameField this.state change, triggers call to render()

Slide 52

Slide 52 text

RENDERING: CHANGES LoginForm UsernameField passes new prop w/ this.state.username value

Slide 53

Slide 53 text

RENDERING: CHANGES LoginForm UsernameField New prop triggers render(), value displayed onscreen ▸ React takes care of all DOM updates

Slide 54

Slide 54 text

CALL RENDER: ONCE ▸ React takes care of all DOM updates ▸ No bit twiddling import { render } from ‘react-dom’ render(, document.getElementById(‘app’))

Slide 55

Slide 55 text

REACT APPROACH REPAINT EVERYTHING ▸ Declare UI based on state ▸ Pass to React as a whole to repaint everything ▸ Simple dev mental model

Slide 56

Slide 56 text

REACT APPROACH REPAINT EVERYTHING ▸ Top-down render ▸ Frame by frame, like game programming ReactDOM.render()

Slide 57

Slide 57 text

CONTROLLING: REPAINT ▸ State change causes repaint / update ▸ Default behavior: `this.state` or `props` change ▸ Can change that behavior

Slide 58

Slide 58 text

COMPONENT UPDATE: Update LIFECYCLE HOOKS time ▸ componentWillReceiveProps shouldComponentUpdate componentWillUpdate render ▸ ▸ ▸ ▸ ▸ componentDidUpdate

Slide 59

Slide 59 text

COMPONENT: DESIGN

Slide 60

Slide 60 text

EXTRACTING: COMMONALITY ▸ Reuse, maintainability, consistency UsernameField PasswordField LoginField

Slide 61

Slide 61 text

EXTRACTING: COMMONALITY const UsernameField = props => {props.label} ▸ Start with similar, duplicated components: ▸ (and a similar PasswordField component)

Slide 62

Slide 62 text

EXTRACTING: COMMONALITY const LoginField = props => {props.label} ▸ Create a common, generalized component:

Slide 63

Slide 63 text

EXTRACTING: COMMONALITY const UsernameField = props => const PasswordField = props => ▸ Wrapped in two specific components:

Slide 64

Slide 64 text

REACT APPROACH COMPOSITION ▸ Polymorphism via composition ▸ No inheritance ▸ Component wrapping is common

Slide 65

Slide 65 text

DOCUMENTING: FOR THE FUTURE npm install prop-types ▸ Discoverability, learning, correct usage ▸ Good citizen ▸ Describing the public interface (props)

Slide 66

Slide 66 text

DOCUMENTING: FOR THE FUTURE import PropTypes from ‘prop-types’ LoginField.propTypes = { label: PropTypes.string, name: PropTypes.string.isRequired, onChange: PropTypes.func.isRequired, type: PropTypes.string } ▸ List all props

Slide 67

Slide 67 text

DOCUMENTING: FOR THE FUTURE ▸ At dev time, if misuse prop, get warning Warning: Failed prop type: The prop `onChange` is marked as required in `LoginField`, but its value is `undefined`.

Slide 68

Slide 68 text

PROVIDING: DEFAULTS LoginField.defaultProps = { type: ‘text’ } ▸ When specific props aren’t sent ▸ Use these values

Slide 69

Slide 69 text

REACT: IN A PROJECT

Slide 70

Slide 70 text

PROJECT: SETUP npm install create-react-app --global ▸ No-config setup tool

Slide 71

Slide 71 text

PROJECT: SETUP create-react-app my-app cd my-app/ npm start open localhost:3000

Slide 72

Slide 72 text

PROJECT: SETUP

Slide 73

Slide 73 text

PROJECT: SETUP import React, { Component } from 'react'; import logo from './logo.svg'; import './App.css'; class App extends Component { render() { return (
logo

Welcome to React

To get started, edit src/App.js and save to reload.

); } } export default App;

Slide 74

Slide 74 text

PROJECT: BUILD ▸ Webpack-based ▸ Everything’s a module ▸ Webpack is powerful ▸ Complicated, and worth learning import './App.css'

Slide 75

Slide 75 text

COMPONENT: STYLING ▸ Many options ▸ Influenced by React community portable, isolated, rebel external, cascade, traditional Inline Stylesheet

Slide 76

Slide 76 text

REACT APPROACH RETHINK BEST PRACTICES ▸ eg, inline styles ▸ or repaint “everything” on update?!

Slide 77

Slide 77 text

COMPONENT: STYLING portable, isolated, rebel external, cascade, traditional CSS Modules Inline Stylesheet isolated, dependencies, composition

Slide 78

Slide 78 text

CSS MODULES: ISOLATED ▸ CSS exposed in export object ▸ Use original selector in code import css from ‘./index.css’

Slide 79

Slide 79 text

CSS MODULES: ISOLATED ▸ Value of selector name in export object is hashed
▸ Making them unique in global namespace ▸ Changes isolated to component my-component.js my-component.css

Slide 80

Slide 80 text

CSS MODULES: EXPLICIT DEPENDENCIES @import “./common.css”; .mySelector { composes: commonSelector; color: red; } class=“mySelector__4ef12 commonSelector__ab5tc”

Slide 81

Slide 81 text

COMPONENT: TESTING npm install jest --save-dev test(‘basic assertion’, () => { expect(true).toEqual(true) }) ▸ Built on Jasmine ▸ Helpful with mocking ▸ Snapshot testing

Slide 82

Slide 82 text

SNAPSHOT: TESTING test(‘render correctly’, () => { const tree = renderer.create() expect(tree).toMatchSnapshot() }) ▸ Similar to taking a screenshot ▸ Comparing changes against original screenshot ▸ But “screenshot” is just a text serialization

Slide 83

Slide 83 text

CLIENT-SIDE: ROUTER ▸ Many options: ▸ react-router ▸ page.js npm install react-router-dom

Slide 84

Slide 84 text

PROJECT: LAYOUT ▸ Instead of by tiers "## controllers "## db "## models "## services $## view "## alerts "## game "## home $## login ▸ By features

Slide 85

Slide 85 text

PROJECT: LAYOUT ▸ Tests next to src login "## __specs__ % "## index.spec.js % $## validators.spec.js "## index.css "## index.js "## sub-component.css "## sub-component.js $## validators.js

Slide 86

Slide 86 text

STATE MANAGEMENT: ▸ Based on Flux pattern ▸ A pattern to help you organize app state ▸ Will complicate your app ▸ If benefit > complexity, do it ▸ Use `props` and `this.state` otherwise REDUX

Slide 87

Slide 87 text

REACT PROJECT: COMPLEXITY React Build toolchain Large project organization Routing Sharing app state ▸ Around the edges Data

Slide 88

Slide 88 text

REACT PROJECT: COMPLEXITY React Routing Data ▸ Component-based ▸ Small to mid-sized ▸ = Joy

Slide 89

Slide 89 text

REACT IN THE: LARGE ▸ Still the best experience I’ve had ▸ Abstractions scale well ▸ Redux implements a solid pattern at scale

Slide 90

Slide 90 text

INTRODUCE REACT: GRADUALLY
My Other-Framework app
ReactDOM.render(, document.getElementById(‘small-piece’)) ▸ Just need a DOM element to own

Slide 91

Slide 91 text

COMPONENTS ARE FOR: SHARING ▸ Great encapsulation ▸ Simple public API ▸ Built-in documentation ▸ Productive community npm publish

Slide 92

Slide 92 text

FIND SUPPORT: IN THE COMMUNITY ▸ Questions: ▸ StackOverflow #reactjs ▸ Forum: discuss.reactjs.org ▸ Chat: “reactiflux” discord, #reactjs IRC ▸ OSS: github.com/reactjs ▸ Docs: facebook.github.io/react

Slide 93

Slide 93 text

FINISH: YOUR TRAINING ▸ Pluralsight.com ▸ Egghead.io ▸ ReactTraining.com ▸ there.. is.. another..

Slide 94

Slide 94 text

A COUPLE: EXAMPLE PROJECTS github.com/jaketrent/wordspies ▸ React + Redux + more: github.com/jaketrent/mastermind-saga ▸ Just React: ▸ (Disregard server portions)

Slide 95

Slide 95 text

USE: WHAT YOU KNOW ▸ You know: ▸ How components work ▸ The React approach ▸ How to start a project ▸

Slide 96

Slide 96 text

THANK YOU JAKETRENT.COM