Skip to content
This repository was archived by the owner on Oct 19, 2018. It is now read-only.

Commit 546a979

Browse files
committed
merged with master
2 parents e214732 + ca09115 commit 546a979

7 files changed

Lines changed: 78 additions & 63 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
It lets you write reactive UI components, with Ruby's elegance using the tried
1111
and true React.js engine. :heart:
1212

13+
[**Visit Our Documentation Site For The Full Story**](https://reactive-ruby.github.io)
14+
1315
### What's this Reactive Ruby?
1416

1517
Reactive Ruby started as a fork of the original react.rb gem, and has since been

lib/react/component.rb

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,6 @@ module Component
1414
def self.included(base)
1515
base.include(API)
1616
base.include(React::Callbacks)
17-
base.instance_eval do
18-
19-
class PropsWrapper < BasicObject
20-
21-
def initialize(props_hash)
22-
@props_hash = props_hash
23-
@processed_params = {}
24-
end
25-
26-
def [](prop)
27-
return unless @props_hash
28-
@props_hash[prop]
29-
end
30-
31-
end
32-
end
3317
base.class_eval do
3418
class_attribute :initial_state
3519
define_callback :before_mount
@@ -145,7 +129,7 @@ def emit(event_name, *args)
145129

146130
def component_will_mount
147131
IsomorphicHelpers.load_context(true) if IsomorphicHelpers.on_opal_client?
148-
@props_wrapper = self.class.const_get("PropsWrapper").new(Hash.new(`#{@native}.props`))
132+
@props_wrapper = self.class.props_wrapper.new(Hash.new(`#{@native}.props`))
149133
set_state! initial_state if initial_state
150134
React::State.initialize_states(self, initial_state)
151135
React::State.set_state_context_to(self) { self.run_callback(:before_mount) }
@@ -198,7 +182,7 @@ def should_component_update?(next_props, next_state)
198182

199183
def component_will_update(next_props, next_state)
200184
React::State.set_state_context_to(self) { self.run_callback(:before_update, Hash.new(next_props), Hash.new(next_state)) }
201-
@props_wrapper = self.class.const_get("PropsWrapper").new(Hash.new(next_props))
185+
@props_wrapper = self.class.props_wrapper.new(Hash.new(next_props))
202186
rescue Exception => e
203187
self.class.process_exception(e, self)
204188
end

lib/react/component/class_methods.rb

Lines changed: 7 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def deprecation_warning(message)
2828
end
2929

3030
def validator
31-
@validator ||= React::Validator.new(self)
31+
@validator ||= Validator.new(self)
3232
end
3333

3434
def prop_types
@@ -55,44 +55,12 @@ def params(&block)
5555
validator.build(&block)
5656
end
5757

58-
def define_param_method(name, param_type)
59-
wrapper = const_get("PropsWrapper")
60-
if param_type == React::Observable
61-
#(@two_way_params ||= []) << name
62-
wrapper.define_method("#{name}") do
63-
@props_hash[name].instance_variable_get("@value") if @props_hash[name]
64-
end
65-
wrapper.define_method("#{name}!") do |*args|
66-
return unless @props_hash[name]
67-
if args.count > 0
68-
current_value = @props_hash[name].instance_variable_get("@value")
69-
@props_hash[name].call args[0]
70-
current_value
71-
else
72-
current_value = @props_hash[name].instance_variable_get("@value")
73-
@props_hash[name].call current_value unless @dont_update_state rescue nil # rescue in case we in middle of render
74-
@props_hash[name]
75-
end
76-
end
77-
define_method("#{name}") { deprecated_params_method("#{name}") }
78-
define_method("#{name}!") { |*args| deprecated_params_method("#{name}!", *args) }
79-
elsif param_type == Proc
80-
wrapper.define_method("#{name}") do |*args, &block|
81-
@props_hash[name].call(*args, &block) if @props_hash[name]
82-
end
83-
define_method("#{name}") { deprecated_params_method("#{name}", *args, &block) }
84-
else
85-
wrapper.define_method("#{name}") do
86-
@processed_params[name] ||= if param_type.respond_to? :_react_param_conversion
87-
param_type._react_param_conversion @props_hash[name]
88-
elsif param_type.is_a?(Array) && param_type[0].respond_to?(:_react_param_conversion)
89-
@props_hash[name].collect { |param| param_type[0]._react_param_conversion param }
90-
else
91-
@props_hash[name]
92-
end
93-
end
94-
define_method("#{name}") { deprecated_params_method("#{name}") }
95-
end
58+
def props_wrapper
59+
@props_wrapper ||= Class.new(PropsWrapper)
60+
end
61+
62+
def define_param(name, param_type)
63+
props_wrapper.define_param(name, param_type, self)
9664
end
9765

9866
def param(*args)
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
module React
2+
module Component
3+
class PropsWrapper < BasicObject
4+
attr_reader :props
5+
6+
def self.define_param(name, param_type, owner)
7+
owner.define_method("#{name}") do
8+
deprecated_params_method("#{name}", *args, &block)
9+
end
10+
if param_type == React::Observable
11+
owner.define_method("#{name}!") do |*args|
12+
deprecated_params_method("#{name}!", *args)
13+
end
14+
define_method("#{name}") do
15+
value_for(name)
16+
end
17+
define_method("#{name}!") do |*args|
18+
current_value = value_for(name)
19+
if args.count > 0
20+
props[name].call args[0]
21+
current_value
22+
else
23+
# rescue in case we in middle of render... What happens during a
24+
# render that causes exception?
25+
# Where does `dont_update_state` come from?
26+
props[name].call current_value unless @dont_update_state rescue nil
27+
props[name]
28+
end
29+
end
30+
elsif param_type == Proc
31+
define_method("#{name}") do |*args, &block|
32+
props[name].call(*args, &block) if props[name]
33+
end
34+
else
35+
define_method("#{name}") do
36+
if param_type.respond_to? :_react_param_conversion
37+
param_type._react_param_conversion props[name]
38+
elsif param_type.is_a?(Array) &&
39+
param_type[0].respond_to?(:_react_param_conversion)
40+
props[name].collect do |param|
41+
param_type[0]._react_param_conversion param
42+
end
43+
else
44+
props[name]
45+
end
46+
end
47+
end
48+
end
49+
50+
def initialize(props)
51+
@props= props|| {}
52+
end
53+
54+
def [](prop)
55+
props[prop]
56+
end
57+
58+
private
59+
60+
def value_for(name)
61+
self[name].instance_variable_get("@value") if self[name]
62+
end
63+
end
64+
end
65+
end

lib/react/validator.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,11 @@ def build(&block)
2020
def requires(name, options = {})
2121
options[:required] = true
2222
define_rule(name, options)
23-
@component_class.define_param_method(name, options[:type])
2423
end
2524

2625
def optional(name, options = {})
2726
options[:required] = false
2827
define_rule(name, options)
29-
@component_class.define_param_method(name, options[:type]) unless name == :params
3028
end
3129

3230
def allow_undefined_props=(allow)
@@ -72,6 +70,7 @@ def rules
7270

7371
def define_rule(name, options = {})
7472
rules[name] = coerce_native_hash_values(options)
73+
@component_class.define_param(name, options[:type]) unless name == :params
7574
end
7675

7776
def errors

lib/reactive-ruby.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
require 'sources/react.js'
33
require 'react/top_level'
44
require 'react/component'
5+
require 'react/component/props_wrapper'
56
require 'react/component/base'
67
require 'react/element'
78
require 'react/event'

spec/react/param_declaration_spec.rb

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
require 'spec_helper'
22

33
if opal?
4-
54
describe 'the param macro' do
6-
75
it "can create and access a required param" do
86
stub_const 'Foo', Class.new(React::Component::Base)
97
Foo.class_eval do
@@ -180,8 +178,6 @@ def render
180178
expect(React.render_to_static_markup(React.create_element(Foo, foo: observer))).to eq('<span>ha!</span>')
181179
expect(current_state).to eq("ha!")
182180
end
183-
184181
end
185-
186182
end
187183
end

0 commit comments

Comments
 (0)