Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Getting into React

Getting into React

Intro presentation on React:

Have you ever wanted to try out React? It's a great library to help you build UIs for your single page apps. Together we'll walk through the basics of this great tool, looking at its component abstraction, how it helps you manage state, and how it will simplify your approach to UI development. We'll give you a feel for what a real React project is like, touching on all the pieces you'll need to try it out yourself. In the end, you'll have a better idea for what React is good for and how you can pick it up to help you on your next project.

Read more on React at jaketrent.com

#reactjs

Jake Trent

May 19, 2017
Tweet

More Decks by Jake Trent

Other Decks in Programming

Transcript

  1. REACT
    GETTING INTO
    JAKE TRENT

    View full-size slide

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

    View full-size slide

  3. INSIDE A:
    COMPONENT

    View full-size slide

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

    View full-size slide

  5. COMPONENTS
    OUTPUT: VIEW
    ▸ Matches the DOM

    For your eyes only

    View full-size slide

  6. 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

    View full-size slide

  7. CUSTOM COMPONENTS:
    ▸ Semantic naming



    ▸ Capitalized == custom
    ▸ Composable hierarchy

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  10. 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

    View full-size slide

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

    View full-size slide

  12. COMPONENT STATE:
    PASS PROPS

    ▸ Like attributes in HTML

    View full-size slide

  13. 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() {}

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  17. COMPONENT:
    RENDERING

    View full-size slide

  18. 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`

    View full-size slide

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

    View full-size slide

  20. 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

    View full-size slide

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

    View full-size slide

  22. 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`

    View full-size slide

  23. 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}

    View full-size slide

  24. 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

    View full-size slide

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

    View full-size slide

  26. 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”

    View full-size slide

  27. in DOM / visible
    COMPONENT MOUNT:
    Mount
    Unmount
    constructor
    componentWillMount
    componentDidMount
    componentWillUnmount





    LIFECYCLE HOOKS
    time

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  30. HANDLING:
    EVENTS

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

    View full-size slide

  31. 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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    }
    }

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  37. 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} />

    }
    }

    View full-size slide

  38. MULTIPLE:
    COMPONENTS

    View full-size slide

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

    View full-size slide

  40. SHARING:
    DATA
    LoginForm
    UsernameField PasswordField
    this.state = {
    username: ‘’
    password: ‘’
    }





    ▸ Data flows down

    View full-size slide

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

    View full-size slide

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




    onChange={props.onChange} />
    onChange={props.onChange} />
    ▸ Changes notify up

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  45. RENDERING:
    CHANGES
    LoginForm
    UsernameField
    ▸ Example: User types username

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  56. COMPONENT UPDATE:
    Update
    LIFECYCLE HOOKS
    time

    componentWillReceiveProps
    shouldComponentUpdate
    componentWillUpdate
    render





    componentDidUpdate

    View full-size slide

  57. COMPONENT:
    DESIGN

    View full-size slide

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

    View full-size slide

  59. EXTRACTING:
    COMMONALITY
    const UsernameField = props =>

    {props.label}
    name=“username”

    onChange={props.onChange} />

    ▸ Start with similar, duplicated components:
    ▸ (and a similar PasswordField component)

    View full-size slide

  60. EXTRACTING:
    COMMONALITY
    const LoginField = props =>

    {props.label}
    name={props.name}
    onChange={props.onChange}
    type={props.type || ‘text’} />

    ▸ Create a common, generalized component:

    View full-size slide

  61. EXTRACTING:
    COMMONALITY
    const UsernameField = props =>
    name=“username”
    onChange={props.onChange} />
    const PasswordField = props =>
    name=“password”
    onChange={props.onChange}
    type=“password” />
    ▸ Wrapped in two specific components:

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  64. 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

    View full-size slide

  65. 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`.

    View full-size slide

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

    View full-size slide

  67. REACT:
    IN A PROJECT

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  70. PROJECT:
    SETUP

    View full-size slide

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



    Welcome to React


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


    );
    }
    }
    export default App;

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  77. 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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  80. 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

    View full-size slide

  81. CLIENT-SIDE:
    ROUTER
    ▸ Many options:
    ▸ react-router
    ▸ page.js



    npm install react-router-dom

    View full-size slide

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

    View full-size slide

  83. 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

    View full-size slide

  84. 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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  88. INTRODUCE REACT:
    GRADUALLY

    My Other-Framework app


    ReactDOM.render(,
    document.getElementById(‘small-piece’))
    ▸ Just need a DOM element to own

    View full-size slide

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

    View full-size slide

  90. 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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  94. THANK YOU
    JAKETRENT.COM

    View full-size slide