react · react.rb opal + reactjs dc ruby users group 2016 brock wilcox [email protected]

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

Upload: others

Post on 24-Aug-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

React.rbOpal + ReactJS

DC Ruby Users Group 2016

Brock [email protected]

Page 2: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

JavaScript!

Page 3: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

CoffeeScript

ClojureScript

TypeScript

Elm

Flow

Page 4: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

Opal

Page 5: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

Compiles Ruby-like language to JS

Page 6: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

Question #1: Is it Ruby?

Page 7: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

Maximally tries to be Ruby

Page 8: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

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: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

In Other Words:

Kinda. Mostly. Lots!

Page 10: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

Question #2: Is it horribly slow?

Page 11: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

Key semantic differences:

· Numbers are JS floats· Symbol == String, are immutable· No threads· No frozen objects· No private/protected

Page 12: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

"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: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

# 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: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

// JS->Ruby integration

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

Page 15: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

# One source of slowdown:# In Ruby, and thus in Opal...

6 * 7

# ...is really...

6.send(:+, 7)

Page 16: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

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

Page 17: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

Question #3: Does it actually work?

Page 18: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

(DEMO Opal IRB)

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

Page 19: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

Works For Me!™

Page 20: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

Question #4: Can you debug it?

Page 21: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

Er... next question please.

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

Page 22: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

Question #5: Oookkkkaayy?

Page 23: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

Volt - Client and Server

Clearwater - Client

Page 24: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

React.rb - Client

Page 25: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

Components

Page 26: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

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

Page 27: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

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

Page 28: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

<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: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

Nested Components

Page 30: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

class GreetApp < React::Component::Base def render Greeting {} endend

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

Page 31: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

Component params

Page 32: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

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: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

Component state

Page 34: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

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: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

Lifecycle events

before_mountafter_mountbefore_receive_propsbefore_updateafter_updatebefore_unmount

Page 36: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

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: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

Callbacks for bubbling upstate changes

Page 38: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

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: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

(DEMO of inline-reactive-ruby)

Page 40: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

Learning App:

White Elephant Gift Selector

(DEMO of WIP app)

Page 41: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

BONUS: Feedback Loops, State, and You

Page 42: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

Clojure

ClojureScript

Reagent

Figwheel

Page 43: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

Amazing workflow!

Page 44: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

(DEMO of liveloader)

Page 45: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

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: React · React.rb Opal + ReactJS DC Ruby Users Group 2016 Brock Wilcox awwaiid@thelackthereof.org

React.rbOpal + ReactJS

DC Ruby Users Group 2016

Brock [email protected]