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

Commit 920ebbb

Browse files
authored
Merge pull request #198 from ruby-hyperloop/feature/refs_callback
Attach actual Ruby instance in ref callback
2 parents 35cacc7 + 24bf4de commit 920ebbb

File tree

5 files changed

+99
-0
lines changed

5 files changed

+99
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Whitespace conventions:
2626

2727
### Deprecated
2828

29+
- Current ref callback behavior is deprecated. Require `"react/ref_callback"` to get the updated behavior. (#188)
2930
- `React.render_to_string` & `React.render_to_static_markup` is deprecated, use `React::Server.render_to_string` & `React::Server.render_to_static_markup` instead. (#186)
3031
- `react/react-source` is deprecated, use `react/react-source-browser` or `react/react-source-server` instead. For most usecase, `react/react-source-browser` is sufficient. If you are using the built-in server side rendering feature, the actual `ReactDOMServer` is already provided by the `react-rails` gem. Therefore, unless you are building a custom server side rendering mechanism, it's not suggested to use `react/react-source-server` in browser code. (#186)
3132

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