$30 off During Our Annual Pro Sale. View Details »

react-rails: an isomorphic match made in heaven

react-rails: an isomorphic match made in heaven

React (which is obvs so hot right now) is hot; It is also a pretty cool view layer, but you have to adopt the entire JS stack to make use of it. OR WAIT, DO YOU!?!?!?!

Let's look at how we can use the Rails asset pipeline, JSON APIs, pre-rendering, and React to build isomorphic rails apps that rule.

We'll start with a quick intro to React, and then get inside Rails to pre-render and render React on the server.

I (JWo) don't say this often, but this is a _compelling_ technology stack.

Jesse Wolgamott

October 21, 2015
Tweet

More Decks by Jesse Wolgamott

Other Decks in Technology

Transcript

  1. REACT-RAILS: AN
    ISOMORPHIC MATCH
    MADE IN HEAVEN
    BY @JWO FOR HOUSTONRB

    View Slide

  2. FIRST, WHAT IS REACT?

    View Slide

  3. CREATED BY FACEBOOK
    DESIGNED TO SOLVE THE STATE
    PROBLEM WITH JQUERY
    WILL RENDER WHENEVER ITS
    INTERNAL STATE CHANGES
    VERY FAST
    WEB COMPONENT BASED

    View Slide

  4. WHY IS IT FAST?
    INSTEAD OF STORING IN THE DOM, REACT HAS ITS OWN
    "VIRTUAL DOM"
    THEN, IT SYNCS CHANGES, REUSING WHAT IT CAN
    https://cdn.tutsplus.com/net/uploads/2013/11/component-
    dom-tree.png

    View Slide

  5. THE VERY BASICS
    EACH REACT COMPONENT MUST HAVE A
    "RENDER" FUNCTION
    THE RENDER FUNCTION HAS HTML INSIDE OF
    IT.
    WHEN HTML+JS ARE IN SAME FILE, WE CALL
    IT JSX

    View Slide

  6. OHHAI
    Run this code
    1
    2
    3
    4
    5
    6
    7
    hosted with ❤ by
    1
    hosted with ❤ by
    v
    a
    r O
    h
    H
    a
    i = R
    e
    a
    c
    t
    .
    c
    r
    e
    a
    t
    e
    C
    l
    a
    s
    s
    (
    {
    r
    e
    n
    d
    e
    r
    (
    ) {
    r
    e
    t
    u
    r
    n <
    d
    i
    v >
    <
    h
    1
    >
    O
    h H
    a
    i T
    h
    e
    r
    e
    !
    <
    /
    h
    1
    >
    <
    /
    d
    i
    v
    >
    }
    }
    )
    ;
    view raw
    ohhai.jsx GitHub
    R
    e
    a
    c
    t
    .
    r
    e
    n
    d
    e
    r
    (
    <
    O
    h
    H
    a
    i
    >
    <
    /
    O
    h
    H
    a
    i
    >
    , d
    o
    c
    u
    m
    e
    n
    t
    .
    b
    o
    d
    y
    )
    ;
    view raw
    very-later.js GitHub

    View Slide

  7. YOU CAN RUN JAVASCRIPT, LIKE
    MAPPING
    Run this code
    1
    2
    3
    4
    5
    6
    7
    8
    9
    1
    0
    1
    1
    1
    2
    1
    3
    1
    4
    1
    5
    1
    6
    1
    7
    hosted with ❤ by
    v
    a
    r N
    u
    m
    b
    e
    r
    s = R
    e
    a
    c
    t
    .
    c
    r
    e
    a
    t
    e
    C
    l
    a
    s
    s
    (
    {
    n
    u
    m
    b
    e
    r
    s
    (
    ) {
    r
    e
    t
    u
    r
    n [
    3
    ,
    4
    ,
    5
    ]
    ;
    }
    ,
    r
    e
    n
    d
    e
    r
    (
    ) {
    r
    e
    t
    u
    r
    n <
    d
    i
    v >
    <
    h
    1
    >
    T
    h
    e
    r
    e a
    r
    e {
    t
    h
    i
    s
    .
    n
    u
    m
    b
    e
    r
    s
    (
    )
    .
    l
    e
    n
    g
    t
    h
    } n
    u
    m
    b
    e
    r
    s
    <
    /
    h
    1
    >
    {
    t
    h
    i
    s
    .
    n
    u
    m
    b
    e
    r
    s
    (
    )
    .
    m
    a
    p
    (
    f
    u
    n
    c
    t
    i
    o
    n
    (
    i
    )
    {
    r
    e
    t
    u
    r
    n <
    p
    >
    T
    h
    e
    r
    e i
    s {
    i
    }
    <
    /
    p
    >
    }
    )
    }
    <
    /
    d
    i
    v
    >
    }
    }
    )
    ;
    R
    e
    a
    c
    t
    .
    r
    e
    n
    d
    e
    r
    (
    <
    N
    u
    m
    b
    e
    r
    s
    >
    <
    /
    N
    u
    m
    b
    e
    r
    s
    >
    , d
    o
    c
    u
    m
    e
    n
    t
    .
    b
    o
    d
    y
    )
    ;
    view raw
    numbers.jsx GitHub

    View Slide

  8. WHAT ABOUT STATE?
    STATE STORES THE COMPONENTS DATA.
    INSTEAD OF IN `DATA-` ATTRIBUTES
    A COMPONENT SETS ITS OWN STATE

    View Slide

  9. CODE THAT USES STATE
    Run this code
    1
    2
    3
    4
    5
    6
    7
    8
    9
    1
    0
    1
    1
    1
    2
    1
    3
    1
    4
    1
    5
    1
    6
    1
    7
    1
    8
    hosted with ❤ by
    v
    a
    r T
    w
    e
    e
    t
    B
    o
    x = R
    e
    a
    c
    t
    .
    c
    r
    e
    a
    t
    e
    C
    l
    a
    s
    s
    (
    {
    g
    e
    t
    I
    n
    i
    t
    i
    a
    l
    S
    t
    a
    t
    e
    (
    )
    {
    r
    e
    t
    u
    r
    n {
    r
    e
    m
    a
    i
    n
    i
    n
    g
    : 1
    4
    0
    }
    }
    ,
    h
    a
    n
    d
    l
    e
    K
    e
    y
    U
    p
    (
    ) {
    v
    a
    r t
    e
    x
    t = t
    h
    i
    s
    .
    r
    e
    f
    s
    .
    t
    w
    e
    e
    t
    t
    w
    e
    e
    t
    .
    g
    e
    t
    D
    O
    M
    N
    o
    d
    e
    (
    )
    .
    v
    a
    l
    u
    e
    ;
    t
    h
    i
    s
    .
    s
    e
    t
    S
    t
    a
    t
    e
    (
    {
    r
    e
    m
    a
    i
    n
    i
    n
    g
    : (
    1
    4
    0 - t
    e
    x
    t
    .
    l
    e
    n
    g
    t
    h
    )
    }
    )
    ;
    }
    ,
    r
    e
    n
    d
    e
    r
    (
    ) {
    r
    e
    t
    u
    r
    n <
    d
    i
    v c
    l
    a
    s
    s
    N
    a
    m
    e
    =
    "
    t
    w
    e
    e
    t
    b
    o
    x
    "
    >
    { t
    h
    i
    s
    .
    s
    t
    a
    t
    e
    .
    r
    e
    m
    a
    i
    n
    i
    n
    g
    } L
    e
    f
    t
    <
    b
    r
    /
    >
    <
    t
    e
    x
    t
    a
    r
    e
    a o
    n
    K
    e
    y
    U
    p
    =
    {
    t
    h
    i
    s
    .
    h
    a
    n
    d
    l
    e
    K
    e
    y
    U
    p
    } r
    e
    f
    =
    "
    t
    w
    e
    e
    t
    t
    w
    e
    e
    t
    "
    >
    <
    /
    t
    e
    x
    t
    a
    r
    e
    a
    >
    <
    /
    d
    i
    v
    >
    }
    }
    )
    ;
    R
    e
    a
    c
    t
    .
    r
    e
    n
    d
    e
    r
    (
    <
    T
    w
    e
    e
    t
    B
    o
    x
    >
    <
    /
    T
    w
    e
    e
    t
    B
    o
    x
    >
    , d
    o
    c
    u
    m
    e
    n
    t
    .
    b
    o
    d
    y
    )
    ;
    view raw
    tweetbox.jsx GitHub

    View Slide

  10. CODE THAT FETCHES DATA
    Run this code
    1
    2
    3
    4
    5
    6
    7
    8
    9
    1
    0
    1
    1
    1
    2
    1
    3
    1
    4
    1
    5
    1
    6
    1
    7
    1
    8
    1
    9
    2
    0
    2
    1
    2
    2
    2
    3
    2
    4
    2
    5
    2
    6
    2
    7
    2
    8
    hosted with ❤ by
    v
    a
    r T
    a
    y
    l
    o
    r = R
    e
    a
    c
    t
    .
    c
    r
    e
    a
    t
    e
    C
    l
    a
    s
    s
    (
    {
    g
    e
    t
    I
    n
    i
    t
    i
    a
    l
    S
    t
    a
    t
    e
    (
    ) {
    r
    e
    t
    u
    r
    n {
    u
    r
    l
    s
    : [
    ]
    }
    ;
    }
    ,
    c
    o
    m
    p
    o
    n
    e
    n
    t
    D
    i
    d
    M
    o
    u
    n
    t
    (
    ) {
    v
    a
    r c
    o
    m
    p
    o
    n
    e
    n
    t = t
    h
    i
    s
    ;
    f
    e
    t
    c
    h
    (
    "
    h
    t
    t
    p
    :
    /
    /
    a
    p
    i
    .
    g
    i
    p
    h
    y
    .
    c
    o
    m
    /
    v
    1
    /
    g
    i
    f
    s
    /
    s
    e
    a
    r
    c
    h
    ?
    q
    =
    t
    a
    y
    l
    o
    r
    +
    s
    w
    i
    f
    t
    &
    a
    p
    i
    _
    k
    e
    y
    =
    d
    c
    6
    z
    a
    T
    O
    x
    F
    J
    m
    z
    C
    "
    )
    .
    t
    h
    e
    n
    (
    f
    u
    n
    c
    t
    i
    o
    n
    (
    r
    e
    s
    p
    o
    n
    s
    e
    ) {
    r
    e
    s
    p
    o
    n
    s
    e
    .
    j
    s
    o
    n
    (
    )
    .
    t
    h
    e
    n
    (
    f
    u
    n
    c
    t
    i
    o
    n
    (
    d
    a
    t
    a
    ) {
    c
    o
    m
    p
    o
    n
    e
    n
    t
    .
    s
    e
    t
    S
    t
    a
    t
    e
    (
    {
    u
    r
    l
    s
    : d
    a
    t
    a
    .
    d
    a
    t
    a
    }
    )
    ;
    }
    )
    ;
    }
    )
    ;
    }
    ,
    r
    e
    n
    d
    e
    r
    (
    ) {
    r
    e
    t
    u
    r
    n <
    d
    i
    v i
    d
    =
    "
    i
    m
    a
    g
    e
    s
    "
    > {
    t
    h
    i
    s
    .
    s
    t
    a
    t
    e
    .
    u
    r
    l
    s
    .
    m
    a
    p
    (
    f
    u
    n
    c
    t
    i
    o
    n
    (
    i
    m
    a
    g
    e
    ) {
    r
    e
    t
    u
    r
    n <
    i
    m
    g s
    r
    c
    =
    {
    i
    m
    a
    g
    e
    .
    i
    m
    a
    g
    e
    s
    .
    f
    i
    x
    e
    d
    _
    h
    e
    i
    g
    h
    t
    .
    u
    r
    l
    }
    >
    <
    /
    i
    m
    g
    >
    }
    )
    }
    <
    /
    d
    i
    v
    >
    }
    }
    )
    ;
    R
    e
    a
    c
    t
    .
    r
    e
    n
    d
    e
    r
    ( <
    T
    a
    y
    l
    o
    r
    /
    > , d
    o
    c
    u
    m
    e
    n
    t
    .
    b
    o
    d
    y
    )
    ;
    view raw
    taylor.jsx GitHub

    View Slide

  11. WHAT ARE PROPS?
    PROPS ARE SENT IN FROM A PARENT
    LIKE URLS.
    OR LIKE THE PRODUCTS TO LOOP OVER

    View Slide

  12. PROPS COME IN FROM THE OUTSIDE
    STATE IS SET FROM THE INSIDE

    View Slide

  13. OK, SO THAT'S REACT.
    HOW DOES THAT HELP
    ME?

    View Slide

  14. JAVASCRIPT BUILD SYSTEMS
    IF YOU DIDN'T WANT TO USE RAILS, YOU
    NEED A BUILD SYSTEM
    YOU NEED A ROUTER
    YOU NEED MANY THINGS

    View Slide

  15. WITH RAILS
    USE RAILS' ASSET PIPELINE
    USE RAILS FOR AUTHENTICATION
    THE GREAT PAGE LOAD
    MIX OF RAILS AND REACT

    View Slide

  16. REAL TIME SYSTEMS

    View Slide

  17. SELF UPDATING SYSTEMS

    View Slide

  18. USE THE BEST, EASIEST, PART OF
    REACT

    View Slide

  19. REACT-RAILS
    A GEM. BECAUSE OF COURSE IT IS
    <
    %
    = r
    e
    a
    c
    t
    _
    c
    o
    m
    p
    o
    n
    e
    n
    t '
    T
    a
    y
    l
    o
    r
    ' %
    >
    RENDERS THE `TAYLOR` REACT COMPONENT TO THAT
    AREA OF THE PAGE

    View Slide

  20. SENDING PROPS
    <
    %
    = r
    e
    a
    c
    t
    _
    c
    o
    m
    p
    o
    n
    e
    n
    t '
    P
    r
    o
    d
    u
    c
    t
    G
    r
    i
    d
    '
    ,
    {
    p
    r
    o
    d
    u
    c
    t
    s
    : @
    p
    r
    o
    d
    u
    c
    t
    s
    } %
    >

    View Slide

  21. SO, YOU CAN SEND PROPS TO A
    PRODUCTGRID
    IT THEN MAKES AN API CALL EVERY 3
    SECONDS TO UPDATE INVENTORY
    COUNT.
    [END]
    NO NEED TO WEIRD RENDERING

    View Slide

  22. OK, BUT I BET THERE'S MORE.

    View Slide

  23. THERE'S MORE

    View Slide

  24. PRERENDER.IO
    AN ENTIRE SERVICE TO RENDER ANGULAR/REACT/ETC FOR
    SEO

    View Slide

  25. <
    %
    = r
    e
    a
    c
    t
    _
    c
    o
    m
    p
    o
    n
    e
    n
    t
    '
    P
    r
    o
    d
    u
    c
    t
    G
    r
    i
    d
    '
    ,
    {
    p
    r
    o
    d
    u
    c
    t
    s
    : @
    p
    r
    o
    d
    u
    c
    t
    s
    } ,
    {
    p
    r
    e
    r
    e
    n
    d
    e
    r
    : t
    r
    u
    e
    }
    %
    >

    View Slide

  26. WHAT JUST HAPPENED

    View Slide

  27. BONUS AWESOME: ACTION CABLE
    NEW IN RAILS 5, AVAILABLE NOW

    View Slide

  28. g
    e
    m '
    a
    c
    t
    i
    o
    n
    c
    a
    b
    l
    e
    '
    , g
    i
    t
    h
    u
    b
    :
    "
    r
    a
    i
    l
    s
    /
    a
    c
    t
    i
    o
    n
    c
    a
    b
    l
    e
    "
    START A PUMA CABLE PROCESS
    HAVE A CHANNEL, AND ALSO A
    SUBSCRIPTION

    View Slide

  29. 1
    2
    3
    4
    5
    6
    7
    8
    9
    1
    0
    1
    1
    1
    2
    1
    3
    1
    4
    1
    5
    1
    6
    1
    7
    1
    8
    1
    9
    2
    0
    2
    1
    2
    2
    2
    3
    2
    4
    2
    5
    2
    6
    2
    7
    2
    8
    2
    9
    3
    0
    3
    1
    3
    2
    hosted with ❤ by
    /
    /
    = r
    e
    q
    u
    i
    r
    e d
    3
    v
    a
    r C
    h
    a
    r
    t
    i
    e = R
    e
    a
    c
    t
    .
    c
    r
    e
    a
    t
    e
    C
    l
    a
    s
    s
    (
    {
    g
    e
    t
    I
    n
    i
    t
    i
    a
    l
    S
    t
    a
    t
    e
    (
    )
    {
    r
    e
    t
    u
    r
    n {
    d
    a
    t
    u
    m
    : [
    {
    "
    v
    a
    l
    u
    e
    s
    "
    : [
    ]
    ,
    "
    k
    e
    y
    "
    : "
    A
    v
    e
    r
    a
    g
    e
    "
    ,
    "
    c
    o
    l
    o
    r
    "
    : '
    #
    f
    f
    7
    f
    0
    e
    '
    }
    ]
    }
    }
    ,
    c
    o
    m
    p
    o
    n
    e
    n
    t
    W
    i
    l
    l
    U
    n
    m
    o
    u
    n
    t
    (
    )
    {
    A
    p
    p
    .
    v
    o
    t
    e
    s
    S
    u
    b
    c
    r
    i
    p
    t
    i
    o
    n = {
    }
    ;
    }
    ,
    c
    o
    m
    p
    o
    n
    e
    n
    t
    W
    i
    l
    l
    M
    o
    u
    n
    t
    (
    )
    {
    v
    a
    r c
    o
    m
    p
    o
    n
    e
    n
    t = t
    h
    i
    s
    ;
    A
    p
    p
    .
    v
    o
    t
    e
    s
    S
    u
    b
    c
    r
    i
    p
    t
    i
    o
    n = A
    p
    p
    .
    c
    a
    b
    l
    e
    .
    s
    u
    b
    s
    c
    r
    i
    p
    t
    i
    o
    n
    s
    .
    c
    r
    e
    a
    t
    e
    (
    "
    V
    o
    t
    e
    s
    C
    h
    a
    n
    n
    e
    l
    "
    , {
    r
    e
    c
    e
    i
    v
    e
    d
    (
    d
    a
    t
    a
    ) {
    c
    o
    m
    p
    o
    n
    e
    n
    t
    .
    s
    e
    t
    S
    t
    a
    t
    e
    (
    {
    d
    a
    t
    u
    m
    : d
    a
    t
    a
    }
    )
    ;
    }
    }
    )
    ;
    }
    ,
    r
    e
    n
    d
    e
    r
    (
    )
    {
    r
    e
    t
    u
    r
    n <
    d
    i
    v
    >
    <
    N
    V
    D
    3
    C
    h
    a
    r
    t t
    y
    p
    e
    =
    '
    l
    i
    n
    e
    C
    h
    a
    r
    t
    ' d
    a
    t
    u
    m
    =
    {
    t
    h
    i
    s
    .
    s
    t
    a
    t
    e
    .
    d
    a
    t
    u
    m
    } >
    <
    /
    N
    V
    D
    3
    C
    h
    a
    r
    t
    >
    <
    /
    d
    i
    v
    >
    }
    }
    )
    ;
    view raw
    votie.jsx GitHub

    View Slide

  30. BROADCAST THE VOTES THAT VOTIE
    LISTENS TO
    A
    c
    t
    i
    o
    n
    C
    a
    b
    l
    e
    .
    s
    e
    r
    v
    e
    r
    .
    b
    r
    o
    a
    d
    c
    a
    s
    t "
    v
    o
    t
    e
    s
    "
    ,
    V
    o
    t
    e
    .
    d
    a
    t
    u
    m

    View Slide

  31. View Slide

  32. View Slide

  33. OK, SO WHAT'S BAD?

    View Slide

  34. ASSET PIPELINE -- WEBPACK TENDS
    TO WORK'ISH
    WEBPACK DEPENDENCIES ARE HARD
    YOU _COULD_ GET RID OF ASSET PIPELINE, BUT I FEEL
    THAT'S A BIG SPICY MEATBALL

    View Slide

  35. PRERENDER TENDS TO WORK WELL,
    BUT RENDERING JSON IN
    CONTROLLER IS HARDER THAN YOU
    THINK.
    JUST USE ACTIVEMODELSERIALIZES

    View Slide

  36. I'M JWO.
    THE IRON YARD
    TEX-MEX CONSULTING
    HANK'S HEROES

    View Slide