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

Getting Started with React

Getting Started with React

I gave this talk at Squares Conference 2016.

http://squaresconference.com

Code demo from the talk…

http://t7.github.io/react-starter

https://github.com/t7/react-starter

Nathan Smith

April 28, 2016
Tweet

More Decks by Nathan Smith

Other Decks in Programming

Transcript

  1. ©2015 T7
    October 13, 2015
    April 28, 2016
    Getting Started
    with React
    squaresconference.com

    View Slide

  2. Slides:
    j.mp/getting-started-react
    GitHub repo:
    github.com/t7/react-starter
    Me, on Twitter:
    @nathansmith

    View Slide

  3. • Father of two rambunctious boys, who
    are big fans of Star Wars and Legos.

    • Self-taught. That just means I pestered
    lots of people until I learned how to do
    this stuff. Yet, I still doubt myself daily.

    • I build the "legacy" software of tomorrow.

    • I generally have a "get off my lawn"
    attitude towards emerging technology.
    Nathan Smith
    Principal Front-End
    Architect
    Introduction

    View Slide

  4. View Slide

  5. Scientific* comparison of "React.js" versus "Angular.js"
    *Not really scientific.

    View Slide

  6. Perhaps unsurprisingly, my off
    the cuff, ill-informed reaction…
    ended up being totally wrong.
    (But, admitting when you're wrong
    is part of being a grown-up, right?)

    View Slide

  7. ©2015 T7
    Software development is a field
    in which it is actually possible to
    know less % overall, even if you
    were to never forget anything.
    There are always new things to
    learn, because the total surface
    area is continuously expanding.

    View Slide

  8. Today, I would like to talk
    to you about the "three Rs."
    •Reading
    •wRiting
    •aRithmetic

    View Slide

  9. There are three fundamental
    aspects of most React apps.
    •React = the "V" (and "C") layer.
    •Redux = the "M" layer.
    •Router = um, the "URL" layer? :)

    View Slide

  10. PROOF POSITIVE OF COOL PROJECTS? LOGOS!
    github.com/reactjs/react-router
    github.com/reactjs/redux
    github.com/facebook/react

    View Slide

  11. Actually, my projects are more like this.
    Accounting.js Babel ECMAScript 6+ ESLint
    Jest Lodash Markdown Moment.js
    NPM PostCSS React ReactDOM
    React Router React Test Utils Redux Sass (SCSS)
    Sass-Lint Standard Webpack window.fetch

    View Slide

  12. npm init -f && npm install --save-dev accounting autoprefixer
    babel-core babel-jest babel-loader babel-plugin-transform-
    runtime babel-preset-es2015 babel-preset-react babel-runtime
    copy-webpack-plugin cross-env css-loader es6-promise eslint
    eslint-config-standard eslint-config-standard-jsx eslint-
    config-standard-react eslint-plugin-promise eslint-plugin-react
    eslint-plugin-standard exports-loader extract-text-webpack-
    plugin html-webpack-plugin husky imports-loader jest-cli json-
    loader lodash marked moment node-sass postcss postcss-loader
    raw-loader react react-addons-test-utils react-dom react-hot-
    loader react-redux react-router redux rimraf sass-lint sass-
    loader style-loader webpack webpack-dev-server whatwg-fetch

    View Slide

  13. How I feel when there's a learning curve.
    (Don't worry, you're not alone.)

    View Slide

  14. ©2015 T7
    Q: "How do you
    eat an elephant?"
    A: "One bite at a time."
    aka: When things seem daunting, break them down into smaller
    chunks. Eventually, those chunks each become understandable.

    View Slide

  15. NOTE:
    First off, let me say that what I am showing
    you today is simply "a" way to do React.
    It is not necessarily "the" (right, only) way.
    This is simply the approach we have settled
    on, after trial and error with various projects.

    View Slide

  16. One thing to keep in mind when working
    with React is the oft-repeated phrase…
    "Everything is a component."
    A component is essentially anything
    that looks like this:
    (Components may contain other components.)

    View Slide

  17. Any time you see something like this…

    content
    …that is usually a React "class," which may or may
    not be an actual JavaScript (ECMAScript 6) class.
    For the purpose of this talk, let's assume they all are.

    View Slide

  18. NOTE:
    Syntax that looks like HTML but is
    embedded (not simply within a string)
    in JavaScript is referred to as "JSX."
    It is an artificial construct that means:
    React.createElement(UppercaseTag, …)

    View Slide

  19. View Slide

  20. View Slide

  21. Conceptually, all React apps are structured like this.
    – great-grandparent
    –– grandparent
    ––– parent
    –––– child
    –––– child
    –– grandparent
    ––– parent
    –––– child
    –––– child

    View Slide

  22. Components talk to each other via "props."

    ^ Here, the parent of is passing
    down a prop called foo, with the value of 'bar'.
    Within the UppercaseTag class, that is usable via…
    this.props.foo // "bar"

    View Slide

  23. Typically, in order for a child to talk to a parent, the parent
    component passes a callback function prop to the child.
    Here's an example of how we use our component.
    handleChange={
    function (e, value) {
    // `e` is the event.
    // `value` is the *.value of the input.
    }
    }
    />

    View Slide

  24. Q: What if the parent does not "care" about the grandparent or the
    child, other than the fact that they are nested within one another?
    – grandparent <—> "parent" props
    –– parent <—> "grandparent" and "child" props
    ––– child <—> "parent" props

    View Slide

  25. A: That is why Redux was created, to allow each component to
    get and/or set changes to a shared object store, aka "app state."
    – grandparent <—> Redux
    –– parent
    ––– child <—> Redux
    ^ If the parent has no inherent reason to care about the shared
    state, it need not be involved as an unnecessary middleman.

    View Slide

  26. NOTE: Dan Abramov is
    on the React team, and is
    the creator of Redux.

    View Slide

  27. NOTE: Ryan Florence is
    one of the creators of
    React Router. He does
    not usually use Redux.

    View Slide

  28. You may sometimes hear about local state as being confined to each
    individual React component. That is correct. Components can have...
    this.state.batmanIdentity // "Bruce Wayne"
    this.state.checked // boolean
    this.state.hasPlaceholder // boolean
    this.state.value // string
    …data that is internal. That self-contained state can be shared with child
    components via props, and can be passed to parents via callback functions.
    Redux "app state" makes things like this.props.foo available to multiple
    components, from a source other than their parents. Redux is a "parent to all."

    View Slide

  29. ©2015 T7
    I think of the relationship between HTML & JS like this:
    Using jQuery or Angular is like
    decorating trees in a forest.
    Using React is like planting a
    magic seed, from which a
    decorated forest grows.

    View Slide

  30. Angular apps usually
    have "decorated" HTML,
    with
    attributes sprinkled
    throughout. HTML loads,
    JS parses it, and then
    applies functionality.

    View Slide

  31. React apps usually have
    a very minimal HTML
    page, with a single
    insertion point, such as
    and then
    the rest of the markup is
    generated entirely by JS.

    View Slide

  32. Having full knowledge of the generated HTML, React is
    able to keep track of the "virtual DOM" and do precise
    updates accordingly. This means you rarely, if ever,
    actually make any of your HTML changes directly.
    No more typing… $('#foo').addClass('bar')

    View Slide

  33. Anatomy of a React Component
    NOTE:
    This is an contrived example. You
    would not normally use internal
    state, when something is just
    directly set via props anyway.
    However, this illustrates the
    relationship between state and
    props. State is internal, whereas
    props come from a component
    that resides a "level above."

    View Slide

  34. Anatomy of a React Component
    NOTE:
    Most of the time, you can safely
    leave out the constructor. It is
    called implicitly, if absent.
    This example also shows how
    you might use defaultProps, to
    provide a fallback placeholder for
    this.props.name. This is handy
    when awaiting an Ajax request.

    View Slide

  35. My React apps normally follow this hierarchy:
    – ..........................// Redux.
    –– ...........................// Router.
    ––– ...................// Router.
    –––– ........................// Redux.
    ––––– ..........................// mine.
    –––––– ..........................// mine.
    ––––––– .....................// mine.
    –––––––– ............// mine.
    ––––––––– ............// mine!
    –––––––––– // etc.

    View Slide

  36. ©2015 T7
    Let's walk through the structure
    of the T7 React starter project.
    First, we will look at the initial index.js
    file, and then progress further into the
    "nested" JS components from there.
    Lastly, we will fire it up in the browser.

    View Slide

  37. View Slide

  38. View Slide

  39. View Slide

  40. View Slide

  41. How I feel about neatly nested nested React components.
    bestpysanky.com/9-pcs-10-Semenov-Russian-Nesting-Dolls-p/nds09000.htm

    View Slide

  42. This index.js file kicks off
    the entire app. It pulls in
    as the first
    component, which wraps
    {routes} and makes
    shared Redux "app
    state" available.

    View Slide

  43. In routes.js we have the
    pattern matching of
    various paths, and their
    respective components.
    We are also setting a
    title prop that will be
    added to the tag
    via a Page component.

    View Slide

  44. This a simple
    level component. In this
    case, it is the fallback for
    when a route is not
    found. We are pulling in a
    Markdown file, with a
    basic "404" message.
    It utilizes the
    layout component,
    wrapping the content.

    View Slide

  45. This is an example of the
    layout component,
    which pulls in app level
    header, main, footer, etc.
    {this.props.children}
    is the Markdown content,
    passed forward from the
    component.

    View Slide

  46. This is the
    component, which was
    being used from within
    the component. It
    contains the logo, and a
    few links in a list.
    It is making use of the
    "Unsemantic" grid, via
    components.

    View Slide

  47. Here, the
    component is basically
    just a pass-through for
    content, simply wrapping
    it in
    for accessibility and
    styling purposes.

    View Slide

  48. ©2015 T7
    So, that covers some of the app structure...
    – index.js
    – routes.js
    – various "page" and "layout" components
    Next, let's take a look at . It is a
    component that maintains internal state, but
    can also be overridden by its parent.

    View Slide

  49. Accessibility is best when done with advanced planning. For the
    components we build, we make sure it is not just an afterthought.

    View Slide

  50. This is actually an example of
    the
    component, a not mutually
    exclusive version of the
    component.

    View Slide

  51. First, the initial selected
    state is set, based on
    props passed in from the
    parent component.
    If it does not exist, then
    the accordion starts out
    completely collapsed.
    We also ensure a unique
    id, to map ARIA roles to
    various elements.

    View Slide

  52. In the event that the parent
    component wants to override
    the internal state, we have
    componentWillReceiveProps
    which will potentially cause a
    state change by calling…
    this.setState({key:val})

    View Slide

  53. The handleClick method
    is called internally when
    an accordion header is
    clicked. This sets the
    component state, and if a
    this.props.handleClick
    callback exists from the
    parent, it will call it too.

    View Slide

  54. Here, an otherwise
    tedious process is made
    fully automatic. That is,
    obviating the manual
    assignment of a unique
    id to each header and
    panel, in order to ensure
    ARIA accessibility hooks
    are properly associated
    to their peer elements.

    View Slide

  55. In the render method, ARIA
    roles are set, based on the
    internal component state.
    For each section of accordion
    content, a child component
    is created.
    Also note, an accordion is
    technically a role="tablist"

    View Slide

  56. ©2015 T7
    Okay, so now we have a basic understanding
    of how an accessible component works.
    Let's now delve into how we can persist
    component state across changes,
    and potentially even across page reloads.
    We will take a look at how a level
    component is hooked up to Redux.

    View Slide

  57. is like Tony Stark. Redux connect adds the "suit" to this.props
    This is done through a process called "currying," when a function returns another, modified function.

    View Slide

  58. First, we need to import
    bindActionCreators and
    connect from redux, and
    react-redux. These will
    allow us to make external
    functions usable within
    the component.

    View Slide

  59. Next, we import our own
    "actions" from the
    various files we have
    stored in the directory
    "/source/redux/actions".
    This directory is not to
    be confused with NPM's
    "/node_modules/redux".

    View Slide

  60. At the end of the file, we
    have Page.propTypes
    validation, so that React
    can warn us if the wrong
    type of props are passed.
    string vs. boolean, etc.

    View Slide

  61. mapStateToProps is
    where external "app
    state" is added to
    via this.props.*

    View Slide

  62. mapDispatchToProps is
    where external functions
    are made available to
    via this.props.*

    View Slide

  63. Lastly, connect uses
    "currying" to make these
    changes innate to .
    You could think of as
    Tony Stark, and the result of
    the connect call as wrapping
    him in an Iron Man suit.
    then has all the
    additional props and functions
    applied to it from Redux.

    View Slide

  64. Thanks to the aforementioned
    currying of connect, we now
    have multiple "action"
    methods available from
    Redux, that can be called from
    within our component.

    View Slide

  65. When we actually make use of
    we pass in
    the selectedFaqAccordion
    "app state," and the callback
    handleClickFaqAccordion
    which triggers our Redux
    "action" state change.

    View Slide

  66. ©2015 T7
    Alright, so that is how things work on a
    component level. But what is all this talk of
    mapping state, mapping dispatch…
    Where does that come from?
    Glad you asked. Next, let's look at these Redux
    concepts: actions, action types, and reducers.

    View Slide

  67. The way Redux layers
    together various state
    changes into one object
    reminds me of the SNL skit
    "Taco Town" where they
    wrap a hard-shell taco in a
    soft-shell taco, in a crepe,
    in a pizza, in a pancake,
    that is deep fried…

    View Slide

  68. View Slide

  69. In "/source/redux/index.js" we
    have what is referred to as a
    rootReducer, which
    aggregates the various child
    reducers. A common mistake
    is to forget to add a new
    reducer here. That can lead to
    frustration when debugging.

    View Slide

  70. In "/source/redux/_types.js"
    there is a list of action types,
    which have been assigned to
    constants. While this may
    seem silly, because they are
    just strings, it enforces unique
    action names. This is helpful
    as your project grows larger.

    View Slide

  71. Each reducer reads from the
    aforementioned _types.js file,
    and potentially pivots based
    on what type of action it is.
    In this case, we are saving
    changes to the selected state
    of the accordion. Notice that
    the state is being get/set by
    utils.storage, which allows
    the state change to persist
    across page loads, saved in
    window.localStorage

    View Slide

  72. This file makes the function
    this.props.updateFaqAccordion
    available to any component
    where connect is used on it.
    It passes forward any changes to
    the accordion's selected state.

    View Slide

  73. ©2015 T7
    And now, a word from our sponsors:
    — ESLint
    — Sass-Lint
    — Jest & React Test Utils
    #srslytho… Unit testing and code linting is
    underrated. So, let's look at how that works.

    View Slide

  74. npm run test

    View Slide

  75. View Slide

  76. By default, Jest wants to be
    helpful and "mock" every file you
    include. But, we can just disable
    that, as we know exactly what we
    want to test. It speeds things up.

    View Slide

  77. We give our test suite a name,
    the same as our .
    Then, we render it into the
    testing concept of a "document,"
    and assign a parent reference.
    Then we can use vanilla DOM
    methods: querySelectorAll, etc.

    View Slide

  78. For each aspect we want to test,
    we pass a string and function to
    "it" — made available by Jest.
    it('does something', …)
    Each resulting pass/fail is shown
    in the command line, via…
    npm run test

    View Slide

  79. ©2015 T7
    Across various projects, we find it helpful to
    have a set of utility methods, which we use by
    attaching them to a parent object, utils.
    Allow me to explain a few of the cool
    and/or more frequently used methods:
    — utils.ajax
    — utils.save

    View Slide

  80. In the "/source/utils/index.js" file,
    we import various utility
    methods, and bundle them under
    a single object, named utils.

    View Slide

  81. In the "/source/utils/_ajax.js" file,
    we have a wrapper around
    window.fetch — which is the
    new HTML5 replacement for the
    quirkiness of XMLHttpRequest.
    You can specify a host, url,
    method, params — sent as query
    or body based on method — and
    callbacks for success/error.
    This file is not presently used in
    the React starter project, but we
    do make use of it in real projects
    that require us to do Ajax.

    View Slide

  82. I use this utils.save method
    quite a bit, when I need to view
    an API response that is too
    cumbersome to read as JSON in
    the browser's developer tools.
    Instead, it causes the browser to
    download a nicely formatted
    *.json file, so I can scroll through
    it using a text editor instead.

    View Slide

  83. Clicking the Save JSON
    button on the "/#/profile"
    page of the demo app will
    download a JSON file…
    form_data.json
    In it, you will see the
    current state of the form
    fields and their values.

    View Slide

  84. Resources:
    • facebook.github.io/react/docs/tutorial.html

    • reactforbeginners.com

    • egghead.io/series/react-fundamentals

    • egghead.io/series/getting-started-with-react-router

    • egghead.io/series/getting-started-with-redux

    • code-cartoons.com/a-cartoon-intro-to-redux-3afb775501a6

    • medium.com/@learnreact/container-components-c0e67432e005

    • medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0


    View Slide

  85. demo
    + q&a

    View Slide

  86. Slides:
    j.mp/getting-started-react
    GitHub repo:
    github.com/t7/react-starter
    Me, on Twitter:
    @nathansmith

    View Slide