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

A React Inspired UI framework in Pure Ruby

zetachang
December 02, 2016

A React Inspired UI framework in Pure Ruby

zetachang

December 02, 2016
Tweet

Other Decks in Programming

Transcript

  1. A React Inspired
    UI framework
    in Pure Ruby
    1

    View Slide

  2. About Me
    • David Chang @zetachang (github, twitter)
    • Software Engineer @ ಋ಑ೌ搚 solda.io
    • Author of HyperReact (a.k.a reactrb) - a ReactJS wrapper.
    2

    View Slide

  3. Building UI is hard
    3

    View Slide

  4. 4

    View Slide

  5. I love JavaScript
    5

    View Slide

  6. I love JavaScript
    6

    View Slide

  7. I love CoffeeScript
    7

    View Slide

  8. I love CoffeeScript
    8

    View Slide

  9. I love TypeScript
    9

    View Slide

  10. I love TypeScript
    10

    View Slide

  11. I love ClojureScript
    11

    View Slide

  12. I love ClojureScript
    12

    View Slide

  13. Hmm..
    13

    View Slide

  14. Tons of languages compile to
    JavaScript
    14

    View Slide

  15. is one of them.
    15

    View Slide

  16. Atoll
    A Ruby Library for Building User
    Interfaces
    16

    View Slide

  17. Atoll vs. React
    17

    View Slide

  18. A React Component (ES6 + JSX҂
    class HelloMessage extends React.Component {
    render() {
    return Hello {this.props.name};
    }
    }
    An Atoll Component (Plain Ruby)
    class HelloMessage < Atoll::Component
    def render
    h('div', nil, "Hello #{props[:name]}")
    end
    end
    18

    View Slide

  19. Built upon Ruby Idioms
    1. Shorter & cleaner method name.
    2. Familiar toolchain (e.g. rake, rspec, sprockets.)
    19

    View Slide

  20. Shorter & Cleaner method name
    • componentWillMount
    • componentDidMount
    • componentWillReceiveProps
    • shouldComponentUpdate
    20

    View Slide

  21. Shorter & Cleaner method name
    • componentWillMount before_mount
    • componentDidMount after_mount
    • componentWillReceiveProps before_receive_props
    • shouldComponentUpdate needs_update?
    21

    View Slide

  22. Familiar Toolchains
    • Sprockets
    • ERB
    • Rake
    • RSpec
    • ....
    • (webpack, gulp, babel, yarn, npm, browserify, rollup, jest,
    mocha, enzyme)
    22

    View Slide

  23. Demo
    23

    View Slide

  24. Ideas taken from React
    • Declarative - predictable & easier to debug.
    • Everything is a Component - Proper separation of
    concerns.
    • Learn Once Write Anywhere - how to render is handled by
    library.
    24

    View Slide

  25. Declarative UI
    25

    View Slide

  26. UI Component:
    26

    View Slide

  27. class Timer < Component
    def initialize
    @state = { second: 0 }
    end
    def after_mount
    $window.every(1) {
    set_state(sec: state[:second] + 1)
    }
    end
    def render
    h('span', nil, "Time elapsed: #{state[:second]}")
    end
    end
    27

    View Slide

  28. Mindset
    1. Always re-render when data change.
    2. Component returns a blueprint instead of the actual
    instance of UI.
    3. Framework do the hard work to generate minimal UI
    updates.
    28

    View Slide

  29. Everything
    is a component
    29

    View Slide

  30. Store Profile
    30

    View Slide

  31. 31

    View Slide

  32. 32

    View Slide

  33. 33

    View Slide

  34. 34

    View Slide

  35. Why Component-Based UI?
    1. A proper separation of concerns for applications.
    2. Fundamental building blocks for application.
    35

    View Slide

  36. Learn Once
    Write Anywhere
    36

    View Slide

  37. Let's render this:
    h("div", nil, "Hello")
    37

    View Slide

  38. 38

    View Slide

  39. 39

    View Slide

  40. Demo
    40

    View Slide

  41. Server Side
    Rendering
    (a.k.a SSR)
    41

    View Slide

  42. Client-side rendering
    • initial request loads the page layout, CSS and JavaScript.
    • some or all of the content isn't included
    Server-side rendering
    • initial request loads the page, layout, CSS, JavaScript
    • and content.
    42

    View Slide

  43. Why Server Side Rendering?
    • Better start-up experience.
    • Visible to search engines (SEO.)
    • User might disable JavaScript.
    43

    View Slide

  44. Current Problems
    1. Component state could not be preserved
    2. Side-effects to make a meaningful first mount must be
    handled at the top level.
    3. JS Runtime is required (e.g. V8, Nashorn.)
    44

    View Slide

  45. Let's fix this in Atoll!
    45

    View Slide

  46. Marshal!
    46

    View Slide

  47. Marshal
    class Foo
    attr_reader :bar
    def initialize
    @bar = "yeah"
    end
    end
    f = Foo.new
    s = Marshal.dump(f)
    # => "\x04\bo:\bFoo\x06:\t@barI\"\tyeah\x06:\x06ET"
    f = Marshal.load(s)
    f.bar
    # => "yeah"
    47

    View Slide

  48. Marshal
    • Serialize object to byte stream.
    • Supported by almost every Rubies (e.g. Opal, MRI,
    RubyMotion.)
    • Almost everything could be marshaled by default.
    48

    View Slide

  49. Demo
    49

    View Slide

  50. On server

    <%= atoll_component(LikeButton) %>
    On client

    Like

    50

    View Slide

  51. What's unlocked?
    • Could be used with existing template toolchain.
    • Server side rendering for mobile app.
    • Pre-render for selective component.
    51

    View Slide

  52. Road ahead
    • Will be free & open sourced
    • Follow @atollrb. !
    • Also follow @opalrb, @RubyMotion
    • It’s simply fun to build this. "
    52

    View Slide