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

Commit 97d887d

Browse files
committed
fixes #125
1 parent 75b63aa commit 97d887d

File tree

3 files changed

+71
-25
lines changed

3 files changed

+71
-25
lines changed

lib/react/component.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ def should_component_update?(next_props, next_state)
179179

180180
def component_will_update(next_props, next_state)
181181
State.set_state_context_to(self) { self.run_callback(:before_update, Hash.new(next_props), Hash.new(next_state)) }
182-
@props_wrapper = self.class.props_wrapper.new(Hash.new(next_props))
182+
@props_wrapper = self.class.props_wrapper.new(Hash.new(next_props), @props_wrapper)
183183
rescue Exception => e
184184
self.class.process_exception(e, self)
185185
end

lib/react/component/props_wrapper.rb

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,23 +33,39 @@ def self.define_param(name, param_type, owner)
3333
end
3434
else
3535
define_method("#{name}") do
36-
@processed_params[name] ||= 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
36+
if @processed_params.has_key? name
37+
@processed_params[name]
4338
else
44-
props[name]
39+
@processed_params[name] = if param_type.respond_to? :_react_param_conversion
40+
param_type._react_param_conversion props[name]
41+
elsif param_type.is_a?(Array) &&
42+
param_type[0].respond_to?(:_react_param_conversion)
43+
props[name].collect do |param|
44+
param_type[0]._react_param_conversion param
45+
end
46+
else
47+
props[name]
48+
end
4549
end
4650
end
4751
end
4852
end
4953

50-
def initialize(props)
54+
def unchanged_processed_params(new_props)
55+
Hash[
56+
*@processed_params.collect do |key, value|
57+
[key, value] if @props[key] == new_props[key]
58+
end.compact.flatten(1)
59+
]
60+
end
61+
62+
def initialize(props, current_props_wrapper=nil)
5163
@props = props || {}
52-
@processed_params = {}
64+
@processed_params = if current_props_wrapper
65+
current_props_wrapper.unchanged_processed_params(props)
66+
else
67+
{}
68+
end
5369
end
5470

5571
def [](prop)

spec/react/param_declaration_spec.rb

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -195,25 +195,55 @@ def render
195195
expect(`window.dummy_log`).to eq(["Warning: Failed propType: In component `Foo`\nProvided prop `foo` could not be converted to BazWoggle"])
196196
end
197197

198-
it "can will only convert once" do
199-
stub_const "BazWoggle", Class.new
200-
BazWoggle.class_eval do
201-
def initialize(kind)
202-
@kind = kind
198+
describe "converts params only once" do
199+
200+
it "not on every access" do
201+
stub_const "BazWoggle", Class.new
202+
BazWoggle.class_eval do
203+
def initialize(kind)
204+
@kind = kind
205+
end
206+
attr_accessor :kind
207+
def self._react_param_conversion(json, validate_only)
208+
new(json[:bazwoggle]) if json[:bazwoggle]
209+
end
203210
end
204-
attr_accessor :kind
205-
def self._react_param_conversion(json, validate_only)
206-
new(json[:bazwoggle]) if json[:bazwoggle]
211+
Foo.class_eval do
212+
param :foo, type: BazWoggle
213+
def render
214+
params.foo.kind = params.foo.kind+1
215+
"#{params.foo.kind}"
216+
end
207217
end
218+
expect(React.render_to_static_markup(React.create_element(Foo, foo: {bazwoggle: 1}))).to eq('<span>2</span>')
208219
end
209-
Foo.class_eval do
210-
param :foo, type: BazWoggle
211-
def render
212-
params.foo.kind = params.foo.kind+1
213-
"#{params.foo.kind}"
220+
221+
it "not after state update" do
222+
stub_const "BazWoggle", Class.new
223+
BazWoggle.class_eval do
224+
def initialize(kind)
225+
@kind = kind
226+
end
227+
attr_accessor :kind
228+
def self._react_param_conversion(json, validate_only)
229+
new(json[:bazwoggle]) if json[:bazwoggle]
230+
end
231+
end
232+
Foo.class_eval do
233+
param :foo, type: BazWoggle
234+
export_state :change_me
235+
before_mount do
236+
params.foo.kind = params.foo.kind+1
237+
end
238+
def render
239+
"#{params.foo.kind} - #{Foo.change_me}"
240+
end
214241
end
242+
div = `document.createElement("div")`
243+
React.render(React.create_element(Foo, foo: {bazwoggle: 1}), div)
244+
Foo.change_me! "updated"
245+
expect(`div.children[0].innerHTML`).to eq("2 - updated")
215246
end
216-
expect(React.render_to_static_markup(React.create_element(Foo, foo: {bazwoggle: 1}))).to eq('<span>2</span>')
217247
end
218248

219249
it "will alias a Proc type param" do

0 commit comments

Comments
 (0)