2016-05-12 dcrug react.rb
TRANSCRIPT
![Page 2: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/2.jpg)
JavaScript!
![Page 3: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/3.jpg)
CoffeeScript
ClojureScript
TypeScript
Elm
Flow
![Page 4: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/4.jpg)
Opal
![Page 5: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/5.jpg)
Compiles Ruby-like language to JS
![Page 6: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/6.jpg)
Question #1: Is it Ruby?
![Page 7: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/7.jpg)
Maximally tries to be Ruby
![Page 8: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/8.jpg)
FAQ: How compatible is Opal?
We run opal against rubyspec as our primary testingsetup. We try to make Opal as compatible as possible,whilst also taking into account restrictions ofJavaScript when applicable. Opal supports themajority of ruby syntax features, as well as a verylarge part of the corelib implementation. We supportmethod_missing, modules, classes, instance_exec,blocks, procs and lots lots more. Opal can compileand run Rspec unmodified, as well as self hosting thecompiler at runtime.
![Page 9: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/9.jpg)
In Other Words:
Kinda. Mostly. Lots!
![Page 10: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/10.jpg)
Question #2: Is it horribly slow?
![Page 11: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/11.jpg)
Key semantic differences:
· Numbers are JS floats· Symbol == String, are immutable· No threads· No frozen objects· No private/protected
![Page 12: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/12.jpg)
"foo" # => "foo", class String < React::Component::Base:foo # => "foo", class String < React::Component::Base
42 # => 42, class Numeric < React::Component::Base3.141 # => 3.142, class Numeric < React::Component::Base5.to_r # Error: undefined method (next ver!)
![Page 13: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/13.jpg)
# Ruby->JS integration
`window.title` # => window.title
%x{ console.log("opal version is: #{ RUBY_ENGINE_VERSION }");}
puts "opal version is: #{ RUBY_ENGINE_VERSION }"
![Page 14: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/14.jpg)
// JS->Ruby integration
Opal.Foo.$new().$hello()
![Page 15: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/15.jpg)
# One source of slowdown:# In Ruby, and thus in Opal...
6 * 7
# ...is really...
6.send(:+, 7)
![Page 16: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/16.jpg)
So far... haven't noticed any speed difference.
![Page 17: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/17.jpg)
Question #3: Does it actually work?
![Page 18: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/18.jpg)
(DEMO Opal IRB)
http://fkchang.github.io/opal-irb/index-jq.html
![Page 19: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/19.jpg)
Works For Me!™
![Page 20: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/20.jpg)
Question #4: Can you debug it?
![Page 21: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/21.jpg)
Er... next question please.
(haha. But seriously, during demos wedebug some things without issue!)
![Page 22: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/22.jpg)
Question #5: Oookkkkaayy?
![Page 23: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/23.jpg)
Volt - Client and Server
Clearwater - Client
![Page 24: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/24.jpg)
React.rb - Client
![Page 25: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/25.jpg)
Components
![Page 26: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/26.jpg)
class Greeting < React::Component::Base def render div { "Hello!" } endend
![Page 27: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/27.jpg)
Document.ready? do React.render( React.create_element(Greeting), Element['#content'] )end
![Page 28: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/28.jpg)
<html> <head> <title>Inline Reactive Ruby Demo</title> <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script> <script src="inline-reactive-ruby.js"></script>
<!-- scripts can be remote or inline --> <script type="text/ruby"> puts "Hello!" </script>
<!-- scripts can be remote or inline --> <script type="text/ruby" src="hello.rb"></script>
</head> <body> <div id="content"></div> </body></html>
![Page 29: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/29.jpg)
Nested Components
![Page 30: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/30.jpg)
class GreetApp < React::Component::Base def render Greeting {} endend
class Greeting < React::Component::Base def render div { "Hello!" } endend
![Page 31: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/31.jpg)
Component params
![Page 32: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/32.jpg)
class GreetApp < React::Component::Base def render Greeting(name: "Friend") endend
class Greeting < React::Component::Base param :name
def render div { "Hello, #{params.name}!" } endend
![Page 33: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/33.jpg)
Component state
![Page 34: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/34.jpg)
class GreetApp < React::Component::Base define_state :name { "Friend" }
def render div { span { "Name: " } input(value: state.name).on(:change) { |e| state.name! e.target.value }
Greeting(name: state.name) } endend
class Greeting < React::Component::Base param :name
def render div { "Hello, #{params.name}!" } endend
![Page 35: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/35.jpg)
Lifecycle events
before_mountafter_mountbefore_receive_propsbefore_updateafter_updatebefore_unmount
![Page 36: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/36.jpg)
class GreetApp < React::Component::Base define_state :name
before_mount do state.name! "Friend" end
def render div { span { "Name: " } input(value: state.name).on(:change) { |e| state.name! e.target.value }
Greeting(name: state.name) } endend
class Greeting < React::Component::Base param :name
def render div { "Hello, #{params.name}!" } endend
![Page 37: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/37.jpg)
Callbacks for bubbling upstate changes
![Page 38: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/38.jpg)
class GreetApp < React::Component::Base define_state :name
before_mount do state.name! "Friend" end
def render div { span { "Name: " } input(value: state.name).on(:change) { |e| state.name! e.target.value }
Greeting(name: state.name, clear_name: lambda { state.name! "" }) } end
end
class Greeting < React::Component::Base param :name param :clear_name, type: Proc
def render div { span { "Hello, #{params.name}!" } a(href: '#') { "CLEAR" }.on(:click) { params.clear_name } } endend
![Page 39: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/39.jpg)
(DEMO of inline-reactive-ruby)
![Page 40: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/40.jpg)
Learning App:
White Elephant Gift Selector
(DEMO of WIP app)
![Page 41: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/41.jpg)
BONUS: Feedback Loops, State, and You
![Page 42: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/42.jpg)
Clojure
ClojureScript
Reagent
Figwheel
![Page 43: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/43.jpg)
Amazing workflow!
![Page 44: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/44.jpg)
(DEMO of liveloader)
![Page 45: 2016-05-12 DCRUG React.rb](https://reader031.vdocuments.mx/reader031/viewer/2022022200/58a6e8421a28abcf0e8b4ba7/html5/thumbnails/45.jpg)
References:
reactrb.org
inline-reactive-ruby
figwheel
Code for this:http://tinyurl.com/20160512-DCRUG-React-rb
WIP White Elephant App:https://github.com/awwaiid/reactrb-elephant