A React Inspired UI framework in Pure Ruby

4b4bc333d8ee7c215476d7715667e8a1?s=47 zetachang
December 02, 2016

A React Inspired UI framework in Pure Ruby

4b4bc333d8ee7c215476d7715667e8a1?s=128

zetachang

December 02, 2016
Tweet

Transcript

  1. 2.

    About Me • David Chang @zetachang (github, twitter) • Software

    Engineer @ ಋ಑ೌ搚 solda.io • Author of HyperReact (a.k.a reactrb) - a ReactJS wrapper. 2
  2. 4.

    4

  3. 13.
  4. 18.

    A React Component (ES6 + JSX҂ class HelloMessage extends React.Component

    { render() { return <div>Hello {this.props.name}</div>; } } An Atoll Component (Plain Ruby) class HelloMessage < Atoll::Component def render h('div', nil, "Hello #{props[:name]}") end end 18
  5. 19.

    Built upon Ruby Idioms 1. Shorter & cleaner method name.

    2. Familiar toolchain (e.g. rake, rspec, sprockets.) 19
  6. 20.

    Shorter & Cleaner method name • componentWillMount • componentDidMount •

    componentWillReceiveProps • shouldComponentUpdate 20
  7. 21.

    Shorter & Cleaner method name • componentWillMount before_mount • componentDidMount

    after_mount • componentWillReceiveProps before_receive_props • shouldComponentUpdate needs_update? 21
  8. 22.

    Familiar Toolchains • Sprockets • ERB • Rake • RSpec

    • .... • (webpack, gulp, babel, yarn, npm, browserify, rollup, jest, mocha, enzyme) 22
  9. 23.
  10. 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
  11. 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
  12. 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
  13. 31.

    31

  14. 32.

    32

  15. 33.

    33

  16. 34.

    34

  17. 35.

    Why Component-Based UI? 1. A proper separation of concerns for

    applications. 2. Fundamental building blocks for application. 35
  18. 38.

    38

  19. 39.

    39

  20. 40.
  21. 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
  22. 43.

    Why Server Side Rendering? • Better start-up experience. • Visible

    to search engines (SEO.) • User might disable JavaScript. 43
  23. 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
  24. 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
  25. 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
  26. 49.
  27. 50.

    On server <!-- Inside ERB template--> <%= atoll_component(LikeButton) %> On

    client <div id='like-btn' data-atoll-state="U2VuZCByZ...."> <button class="btn btn-like">Like</button> </div> 50
  28. 51.

    What's unlocked? • Could be used with existing template toolchain.

    • Server side rendering for mobile app. • Pre-render for selective component. 51
  29. 52.

    Road ahead • Will be free & open sourced •

    Follow @atollrb. ! • Also follow @opalrb, @RubyMotion • It’s simply fun to build this. " 52