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

Commit 8287f2d

Browse files
committed
Attach actual Ruby instance in ref callback
1 parent 35cacc7 commit 8287f2d

File tree

4 files changed

+92
-0
lines changed

4 files changed

+92
-0
lines changed

lib/react/api.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,16 @@ def self.convert_props(properties)
142142
props["className"] = value
143143
elsif ["style", "dangerously_set_inner_HTML"].include? key
144144
props[lower_camelize(key)] = value.to_n
145+
elsif key == 'ref' && value.is_a?(Proc)
146+
unless React.const_defined?(:RefsCallbackExtension)
147+
%x{
148+
console.error(
149+
"Warning: Using deprecated behavior of ref callback,",
150+
"require \"react/ref_callback\" to get the correct behavior."
151+
);
152+
}
153+
end
154+
props[key] = value
145155
elsif React::HASH_ATTRIBUTES.include?(key) && value.is_a?(Hash)
146156
value.each { |k, v| props["#{key}-#{k.tr('_', '-')}"] = v.to_n }
147157
else

lib/react/ref_callback.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
require 'react/native_library'
2+
3+
module React
4+
module RefsCallbackExtension
5+
end
6+
7+
class API
8+
class << self
9+
alias :orig_convert_props :convert_props
10+
end
11+
12+
def self.convert_props(properties)
13+
props = self.orig_convert_props(properties)
14+
props.map do |key, value|
15+
if key == "ref" && value.is_a?(Proc)
16+
new_proc = Proc.new do |native_inst|
17+
if `#{native_inst}._getOpalInstance !== undefined`
18+
value.call(`#{native_inst}._getOpalInstance()`)
19+
elsif `React.findDOMNode !== undefined && #{native_inst}.nodeType === undefined`
20+
value.call(`React.findDOMNode(#{native_inst})`)
21+
else
22+
value.call(native_inst)
23+
end
24+
end
25+
props[key] = new_proc
26+
end
27+
end
28+
props
29+
end
30+
end
31+
end

spec/react/refs_callback_spec.rb

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
describe 'Refs callback' do
2+
before do
3+
stub_const 'Foo', Class.new
4+
Foo.class_eval do
5+
include React::Component
6+
end
7+
end
8+
9+
it "is invoked with the actual Ruby instance" do
10+
stub_const 'Bar', Class.new
11+
Bar.class_eval do
12+
include React::Component
13+
def render
14+
React.create_element('div')
15+
end
16+
end
17+
18+
stub_const 'MyBar', nil
19+
Foo.class_eval do
20+
def my_bar=(bar)
21+
MyBar = bar
22+
end
23+
24+
def render
25+
React.create_element(Bar, ref: method(:my_bar=).to_proc)
26+
end
27+
end
28+
29+
element = React.create_element(Foo)
30+
React::Test::Utils.render_into_document(element)
31+
expect(MyBar).to be_a(Bar)
32+
end
33+
34+
it "is invoked with the actual DOM node" do
35+
stub_const 'MyDiv', nil
36+
Foo.class_eval do
37+
def my_div=(div)
38+
MyDiv = div
39+
end
40+
41+
def render
42+
React.create_element('div', ref: method(:my_div=).to_proc)
43+
end
44+
end
45+
46+
element = React.create_element(Foo)
47+
React::Test::Utils.render_into_document(element)
48+
expect(`#{MyDiv}.nodeType`).to eq(1)
49+
end
50+
end

spec/spec_helper.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ def ruby?
2121
require 'react/test/rspec'
2222
require 'react/test/utils'
2323
require 'react/top_level_render'
24+
require 'react/ref_callback'
2425
require 'react/server'
2526

2627
require File.expand_path('../support/react/spec_helpers', __FILE__)

0 commit comments

Comments
 (0)