46
React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox [email protected]

2016-05-12 DCRUG React.rb

  • Upload
    awwaiid

  • View
    1.986

  • Download
    0

Embed Size (px)

Citation preview

Page 1: 2016-05-12 DCRUG React.rb

React.rbOpal + ReactJS

DC Ruby Users Group 2016

Brock [email protected]

Page 2: 2016-05-12 DCRUG React.rb

JavaScript!

Page 3: 2016-05-12 DCRUG React.rb

CoffeeScript

ClojureScript

TypeScript

Elm

Flow

Page 4: 2016-05-12 DCRUG React.rb

Opal

Page 5: 2016-05-12 DCRUG React.rb

Compiles Ruby-like language to JS

Page 6: 2016-05-12 DCRUG React.rb

Question #1: Is it Ruby?

Page 7: 2016-05-12 DCRUG React.rb

Maximally tries to be Ruby

Page 8: 2016-05-12 DCRUG React.rb

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

In Other Words:

Kinda. Mostly. Lots!

Page 10: 2016-05-12 DCRUG React.rb

Question #2: Is it horribly slow?

Page 11: 2016-05-12 DCRUG React.rb

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

"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

# 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

// JS->Ruby integration

Opal.Foo.$new().$hello()

Page 15: 2016-05-12 DCRUG React.rb

# 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

So far... haven't noticed any speed difference.

Page 17: 2016-05-12 DCRUG React.rb

Question #3: Does it actually work?

Page 18: 2016-05-12 DCRUG React.rb

(DEMO Opal IRB)

http://fkchang.github.io/opal-irb/index-jq.html

Page 19: 2016-05-12 DCRUG React.rb

Works For Me!™

Page 20: 2016-05-12 DCRUG React.rb

Question #4: Can you debug it?

Page 21: 2016-05-12 DCRUG React.rb

Er... next question please.

(haha. But seriously, during demos wedebug some things without issue!)

Page 22: 2016-05-12 DCRUG React.rb

Question #5: Oookkkkaayy?

Page 23: 2016-05-12 DCRUG React.rb

Volt - Client and Server

Clearwater - Client

Page 24: 2016-05-12 DCRUG React.rb

React.rb - Client

Page 25: 2016-05-12 DCRUG React.rb

Components

Page 26: 2016-05-12 DCRUG React.rb

class Greeting < React::Component::Base def render div { "Hello!" } endend

Page 27: 2016-05-12 DCRUG React.rb

Document.ready? do React.render( React.create_element(Greeting), Element['#content'] )end

Page 28: 2016-05-12 DCRUG React.rb

<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

Nested Components

Page 30: 2016-05-12 DCRUG React.rb

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

Component params

Page 32: 2016-05-12 DCRUG React.rb

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

Component state

Page 34: 2016-05-12 DCRUG React.rb

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

Lifecycle events

before_mountafter_mountbefore_receive_propsbefore_updateafter_updatebefore_unmount

Page 36: 2016-05-12 DCRUG React.rb

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

Callbacks for bubbling upstate changes

Page 38: 2016-05-12 DCRUG React.rb

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

(DEMO of inline-reactive-ruby)

Page 40: 2016-05-12 DCRUG React.rb

Learning App:

White Elephant Gift Selector

(DEMO of WIP app)

Page 41: 2016-05-12 DCRUG React.rb

BONUS: Feedback Loops, State, and You

Page 42: 2016-05-12 DCRUG React.rb

Clojure

ClojureScript

Reagent

Figwheel

Page 43: 2016-05-12 DCRUG React.rb

Amazing workflow!

Page 44: 2016-05-12 DCRUG React.rb

(DEMO of liveloader)

Page 45: 2016-05-12 DCRUG React.rb

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

Page 46: 2016-05-12 DCRUG React.rb

React.rbOpal + ReactJS

DC Ruby Users Group 2016

Brock [email protected]