isomorfeus-react 16.6.8 → 16.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +39 -413
- data/lib/isomorfeus-react-base.rb +55 -0
- data/lib/isomorfeus-react-component.rb +20 -0
- data/lib/isomorfeus-react-lucid.rb +39 -0
- data/lib/isomorfeus-react-material-ui.rb +41 -0
- data/lib/isomorfeus-react-redux-component.rb +25 -0
- data/lib/isomorfeus-react.rb +4 -101
- data/lib/isomorfeus/config.rb +3 -8
- data/lib/isomorfeus/top_level_browser.rb +1 -1
- data/lib/lucid_app/api.rb +1 -12
- data/lib/lucid_app/mixin.rb +1 -0
- data/lib/lucid_app/native_component_constructor.rb +10 -0
- data/lib/lucid_component/api.rb +1 -1
- data/lib/lucid_component/initializer.rb +5 -5
- data/lib/lucid_component/mixin.rb +1 -0
- data/lib/lucid_component/native_component_constructor.rb +13 -3
- data/lib/lucid_material/app/base.rb +9 -0
- data/lib/lucid_material/app/mixin.rb +20 -0
- data/lib/lucid_material/app/native_component_constructor.rb +116 -0
- data/lib/lucid_material/component/api.rb +19 -0
- data/lib/lucid_material/component/base.rb +9 -0
- data/lib/lucid_material/component/mixin.rb +21 -0
- data/lib/lucid_material/component/native_component_constructor.rb +158 -0
- data/lib/react.rb +13 -5
- data/lib/react/children.rb +35 -0
- data/lib/react/component/api.rb +5 -91
- data/lib/react/component/callbacks.rb +103 -0
- data/lib/react/component/elements.rb +3 -23
- data/lib/react/component/features.rb +12 -29
- data/lib/react/component/initializer.rb +2 -2
- data/lib/react/component/mixin.rb +1 -0
- data/lib/react/component/native_component_constructor.rb +7 -0
- data/lib/react/component/props.rb +13 -1
- data/lib/react/component/resolution.rb +14 -15
- data/lib/react/component/styles.rb +23 -0
- data/lib/react/context_wrapper.rb +4 -0
- data/lib/react/function_component/api.rb +83 -0
- data/lib/react/function_component/base.rb +9 -0
- data/lib/react/function_component/creator.rb +19 -65
- data/lib/react/function_component/event_handler.rb +13 -0
- data/lib/react/function_component/mixin.rb +14 -0
- data/lib/react/function_component/resolution.rb +17 -15
- data/lib/react/memo_component/base.rb +9 -0
- data/lib/react/memo_component/creator.rb +32 -0
- data/lib/react/memo_component/mixin.rb +14 -0
- data/lib/react/native_constant_wrapper.rb +1 -11
- data/lib/react/pure_component/mixin.rb +2 -0
- data/lib/react/redux_component/api.rb +1 -93
- data/lib/react/redux_component/initializer.rb +5 -5
- data/lib/react/redux_component/mixin.rb +1 -0
- data/lib/react/redux_component/native_component_constructor.rb +13 -3
- data/lib/react/redux_component/reducers.rb +29 -35
- data/lib/react/ref.rb +4 -0
- data/lib/react/version.rb +1 -1
- data/lib/react_dom.rb +9 -3
- metadata +70 -8
- data/lib/lucid_router.rb +0 -18
- data/lib/react/function_component/runner.rb +0 -19
@@ -0,0 +1,103 @@
|
|
1
|
+
module React
|
2
|
+
module Component
|
3
|
+
module Callbacks
|
4
|
+
def self.included(base)
|
5
|
+
base.instance_exec do
|
6
|
+
def component_did_catch(&block)
|
7
|
+
# TODO convert error and info
|
8
|
+
%x{
|
9
|
+
var fun = function(error, info) {
|
10
|
+
Opal.React.active_redux_components.push(this.__ruby_instance);
|
11
|
+
#{`this.__ruby_instance`.instance_exec(`error`, `info`, &block)};
|
12
|
+
Opal.React.active_redux_components.pop();
|
13
|
+
}
|
14
|
+
if (self.lucid_react_component) { self.lucid_react_component.prototype.componentDidCatch = fun; }
|
15
|
+
else { self.react_component.prototype.componentDidCatch = fun; }
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def component_did_mount(&block)
|
20
|
+
%x{
|
21
|
+
var fun = function() {
|
22
|
+
Opal.React.active_redux_components.push(this.__ruby_instance);
|
23
|
+
#{`this.__ruby_instance`.instance_exec(&block)};
|
24
|
+
Opal.React.active_redux_components.pop();
|
25
|
+
}
|
26
|
+
if (self.lucid_react_component) { self.lucid_react_component.prototype.componentDidMount = fun; }
|
27
|
+
else { self.react_component.prototype.componentDidMount = fun; }
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def component_did_update(&block)
|
32
|
+
%x{
|
33
|
+
var fun = function(prev_props, prev_state, snapshot) {
|
34
|
+
Opal.React.active_redux_components.push(this.__ruby_instance);
|
35
|
+
#{`this.__ruby_instance`.instance_exec(`Opal.React.Component.Props.$new(prev_props)`,
|
36
|
+
`Opal.React.Component.State.$new({state: prev_state})`,
|
37
|
+
`snapshot`, &block)};
|
38
|
+
Opal.React.active_redux_components.pop();
|
39
|
+
}
|
40
|
+
if (self.lucid_react_component) { self.lucid_react_component.prototype.componentDidUpdate = fun; }
|
41
|
+
else { self.react_component.prototype.componentDidUpdate = fun; }
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def component_will_unmount(&block)
|
46
|
+
%x{
|
47
|
+
var fun = function() {
|
48
|
+
if (typeof this.unsubscriber === "function") { this.unsubscriber(); };
|
49
|
+
Opal.React.active_redux_components.push(this.__ruby_instance);
|
50
|
+
#{`this.__ruby_instance`.instance_exec(&block)};
|
51
|
+
Opal.React.active_redux_components.pop();
|
52
|
+
}
|
53
|
+
if (self.lucid_react_component) { self.lucid_react_component.prototype.componentWillUnmount = fun; }
|
54
|
+
else { self.react_component.prototype.componentWillUnmount = fun; }
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
def get_derived_state_from_error(&block)
|
59
|
+
# TODO convert error
|
60
|
+
%x{
|
61
|
+
var fun = function(error) {
|
62
|
+
var result = #{`this.__ruby_instance`.instance_exec(`error`, &block)};
|
63
|
+
if (result === null) { return null; }
|
64
|
+
if (typeof result.$to_n === 'function') { return result.$to_n() }
|
65
|
+
return result;
|
66
|
+
}
|
67
|
+
if (self.lucid_react_component) { self.lucid_react_component.prototype.getDerivedStateFromError = fun; }
|
68
|
+
else { self.react_component.prototype.getDerivedStateFromError = fun; }
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
def get_derived_state_from_props(&block)
|
73
|
+
%x{
|
74
|
+
var fun = function(props, state) {
|
75
|
+
Opal.React.active_redux_components.push(this.__ruby_instance);
|
76
|
+
#{`this.__ruby_instance`.instance_exec(`Opal.React.Component.Props.$new(props)`,
|
77
|
+
`Opal.React.Component.State.$new({state: state})`,
|
78
|
+
&block)};
|
79
|
+
Opal.React.active_redux_components.pop();
|
80
|
+
}
|
81
|
+
if (self.lucid_react_component) { self.lucid_react_component.prototype.getDerivedStateFromProps = fun; }
|
82
|
+
else { self.react_component.prototype.getDerivedStateFromProps = fun; }
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
def get_snapshot_before_update(&block)
|
87
|
+
%x{
|
88
|
+
var fun = function(prev_props, prev_state) {
|
89
|
+
Opal.React.active_redux_components.push(this.__ruby_instance);
|
90
|
+
#{`this.__ruby_instance`.instance_exec(`Opal.React.Component.Props.$new(prev_props)`,
|
91
|
+
`Opal.React.Component.State.$new({state: prev_state})`,
|
92
|
+
&block)};
|
93
|
+
Opal.React.active_redux_components.pop();
|
94
|
+
}
|
95
|
+
if (self.lucid_react_component) { self.lucid_react_component.prototype.getSnapshotBeforeUpdate = fun; }
|
96
|
+
else { self.react_component.prototype.getSnapshotBeforeUpdate = fun; }
|
97
|
+
}
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -2,6 +2,7 @@ module React
|
|
2
2
|
module Component
|
3
3
|
module Elements
|
4
4
|
# https://www.w3.org/TR/html52/fullindex.html#index-elements
|
5
|
+
# https://www.w3.org/TR/SVG11/eltindex.html
|
5
6
|
SUPPORTED_HTML_AND_SVG_ELEMENTS = %w[
|
6
7
|
a abbr address area article aside audio
|
7
8
|
b base bdi bdo blockquote body br button
|
@@ -24,10 +25,6 @@ module React
|
|
24
25
|
u ul
|
25
26
|
var video
|
26
27
|
wbr
|
27
|
-
] +
|
28
|
-
# https://www.w3.org/TR/SVG11/eltindex.html
|
29
|
-
# elements listed above not mentioned a second time
|
30
|
-
%w[
|
31
28
|
altGlyph altGlyphDef altGlyphItem animate animateColor animateMotion animateTransform
|
32
29
|
circle clipPath color-profile cursor
|
33
30
|
defs desc
|
@@ -50,29 +47,12 @@ module React
|
|
50
47
|
view vkern
|
51
48
|
]
|
52
49
|
|
53
|
-
|
54
50
|
SUPPORTED_HTML_AND_SVG_ELEMENTS.each do |element|
|
55
51
|
define_method(element) do |*args, &block|
|
56
|
-
|
57
|
-
if (args.length > 0) {
|
58
|
-
var last_arg = args[args.length - 1];
|
59
|
-
if (typeof last_arg === 'string' || last_arg instanceof String) {
|
60
|
-
if (args.length === 1) { Opal.React.internal_render(element, null, last_arg, null); }
|
61
|
-
else { Opal.React.internal_render(element, args[0], last_arg, null); }
|
62
|
-
} else { Opal.React.internal_render(element, args[0], null, block); }
|
63
|
-
} else { Opal.React.internal_render(element, null, null, block); }
|
64
|
-
}
|
52
|
+
`Opal.React.internal_prepare_args_and_render(element, args, block)`
|
65
53
|
end
|
66
54
|
define_method(`element.toUpperCase()`) do |*args, &block|
|
67
|
-
|
68
|
-
if (args.length > 0) {
|
69
|
-
var last_arg = args[args.length - 1];
|
70
|
-
if (typeof last_arg === 'string' || last_arg instanceof String) {
|
71
|
-
if (args.length === 1) { Opal.React.internal_render(element, null, last_arg, null); }
|
72
|
-
else { Opal.React.internal_render(element, args[0], last_arg, null); }
|
73
|
-
} else { Opal.React.internal_render(element, args[0], null, block); }
|
74
|
-
} else { Opal.React.internal_render(element, null, null, block); }
|
75
|
-
}
|
55
|
+
`Opal.React.internal_prepare_args_and_render(element, args, block)`
|
76
56
|
end
|
77
57
|
end
|
78
58
|
end
|
@@ -2,18 +2,17 @@ module React
|
|
2
2
|
module Component
|
3
3
|
module Features
|
4
4
|
def Fragment(*args, &block)
|
5
|
-
|
6
|
-
if (args.length > 0) {
|
7
|
-
var last_arg = args[args.length - 1];
|
8
|
-
if (typeof last_arg === 'string' || last_arg instanceof String) {
|
9
|
-
if (args.length === 1) { Opal.React.internal_render(React.Fragment, null, last_arg, null); }
|
10
|
-
else { Opal.React.internal_render(Opal.global.React.Fragment, args[0], last_arg, null); }
|
11
|
-
} else { Opal.React.internal_render(Opal.global.React.Fragment, args[0], null, block); }
|
12
|
-
} else { Opal.React.internal_render(Opal.global.React.Fragment, null, null, block); }
|
13
|
-
}
|
5
|
+
`Opal.React.internal_prepare_args_and_render(Opal.global.React.Fragment, args, block)`
|
14
6
|
end
|
15
7
|
|
16
|
-
def Portal(
|
8
|
+
def Portal(element_or_query, &block)
|
9
|
+
if `(typeof element_or_query === 'string')` || (`(typeof element_or_query.$class === 'function')` && element_or_query.class == String)
|
10
|
+
element = `document.body.querySelector(element_or_query)`
|
11
|
+
elsif `(typeof element_or_query.$is_a === 'function')` && element_or_query.is_a?(Browser::DOM::Node)
|
12
|
+
element = element_or_query.to_n
|
13
|
+
else
|
14
|
+
element = element_or_query
|
15
|
+
end
|
17
16
|
%x{
|
18
17
|
var children = null;
|
19
18
|
var block_result = null;
|
@@ -27,34 +26,18 @@ module React
|
|
27
26
|
Opal.React.render_buffer[Opal.React.render_buffer.length - 1].push(block_result);
|
28
27
|
}
|
29
28
|
}
|
30
|
-
var react_element = Opal.global.React.createPortal(Opal.React.render_buffer.pop(),
|
29
|
+
var react_element = Opal.global.React.createPortal(Opal.React.render_buffer.pop(), element);
|
31
30
|
Opal.React.render_buffer[Opal.React.render_buffer.length - 1].push(react_element);
|
32
31
|
return null;
|
33
32
|
}
|
34
33
|
end
|
35
34
|
|
36
35
|
def StrictMode(*args, &block)
|
37
|
-
|
38
|
-
if (args.length > 0) {
|
39
|
-
var last_arg = args[args.length - 1];
|
40
|
-
if (typeof last_arg === 'string' || last_arg instanceof String) {
|
41
|
-
if (args.length === 1) { Opal.React.internal_render(Opal.global.React.StrictMode, null, last_arg, null); }
|
42
|
-
else { Opal.React.internal_render(Opal.global.React.StrictMode, args[0], last_arg, null); }
|
43
|
-
} else { Opal.React.internal_render(Opal.global.React.StrictMode, args[0], null, block); }
|
44
|
-
} else { Opal.React.internal_render(Opal.global.React.StrictMode, null, null, block); }
|
45
|
-
}
|
36
|
+
`Opal.React.internal_prepare_args_and_render(Opal.global.React.StrictMode, args, block)`
|
46
37
|
end
|
47
38
|
|
48
39
|
def Suspense(*args, &block)
|
49
|
-
|
50
|
-
if (args.length > 0) {
|
51
|
-
var last_arg = args[args.length - 1];
|
52
|
-
if (typeof last_arg === 'string' || last_arg instanceof String) {
|
53
|
-
if (args.length === 1) { Opal.React.internal_render(Opal.global.React.Suspense, null, last_arg, null); }
|
54
|
-
else { Opal.React.internal_render(Opal.global.React.Suspense, args[0], last_arg, null); }
|
55
|
-
} else { Opal.React.internal_render(Opal.global.React.Suspense, args[0], null, block); }
|
56
|
-
} else { Opal.React.internal_render(Opal.global.React.Suspense, null, null, block); }
|
57
|
-
}
|
40
|
+
`Opal.React.internal_prepare_args_and_render(Opal.global.React.Suspense, args, block)`
|
58
41
|
end
|
59
42
|
end
|
60
43
|
end
|
@@ -3,8 +3,8 @@ module React
|
|
3
3
|
module Initializer
|
4
4
|
def initialize(native_component)
|
5
5
|
@native = native_component
|
6
|
-
@props =
|
7
|
-
@state =
|
6
|
+
@props = `Opal.React.Component.Props.$new(#@native.props)`
|
7
|
+
@state = `Opal.React.Component.State.$new(#@native)`
|
8
8
|
end
|
9
9
|
end
|
10
10
|
end
|
@@ -9,6 +9,7 @@ module React
|
|
9
9
|
base.extend(::React::Component::EventHandler)
|
10
10
|
base.include(::React::Component::Elements)
|
11
11
|
base.include(::React::Component::API)
|
12
|
+
base.include(::React::Component::Callbacks)
|
12
13
|
base.include(::React::Component::UnsafeAPI)
|
13
14
|
base.include(::React::Component::Initializer)
|
14
15
|
base.include(::React::Component::Features)
|
@@ -36,6 +36,13 @@ module React
|
|
36
36
|
static get displayName() {
|
37
37
|
return #{component_name};
|
38
38
|
}
|
39
|
+
render() {
|
40
|
+
Opal.React.render_buffer.push([]);
|
41
|
+
Opal.React.active_components.push(this);
|
42
|
+
#{`this.__ruby_instance`.instance_exec(&`base.render_block`)};
|
43
|
+
Opal.React.active_components.pop();
|
44
|
+
return Opal.React.render_buffer.pop();
|
45
|
+
}
|
39
46
|
shouldComponentUpdate(next_props, next_state) {
|
40
47
|
if (base.has_custom_should_component_update) {
|
41
48
|
return this.__ruby_instance["$should_component_update"](#{(Hash.new(next_props))}, #{Hash.new(next_state)});
|
@@ -4,13 +4,25 @@ module React
|
|
4
4
|
include ::Native::Wrapper
|
5
5
|
|
6
6
|
def method_missing(prop, *args, &block)
|
7
|
-
|
7
|
+
%x{
|
8
|
+
var prop_name = Opal.React.lower_camelize(prop);
|
9
|
+
if (typeof #@native[prop_name] === 'undefined') {
|
10
|
+
return #{nil};
|
11
|
+
} else {
|
12
|
+
return #@native[prop_name];
|
13
|
+
}
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def classes
|
18
|
+
@classes ||= `Opal.React.Component.Styles.$new(#@native.classes)`
|
8
19
|
end
|
9
20
|
|
10
21
|
def isomorfeus_store
|
11
22
|
@native.JS[:isomorfeus_store]
|
12
23
|
end
|
13
24
|
|
25
|
+
# for router convenience
|
14
26
|
def history
|
15
27
|
return @history if @history
|
16
28
|
return nil unless @native.JS[:history]
|
@@ -34,42 +34,41 @@ module React
|
|
34
34
|
var component_type = typeof Opal.global[component_name];
|
35
35
|
if (component_type === "function" || component_type === "object") {
|
36
36
|
component = Opal.global[component_name];
|
37
|
-
}
|
38
|
-
else {
|
37
|
+
} else {
|
39
38
|
var modules = self.$class().$to_s().split("::");
|
40
39
|
var modules_length = modules.length - 1;
|
41
|
-
// modules.unshift('');
|
42
40
|
var module;
|
43
41
|
var constant;
|
44
42
|
for (var i = modules_length; i > 0; i--) {
|
45
43
|
try {
|
46
44
|
module = modules.slice(0, i).join('::')
|
47
45
|
constant = self.$class().$const_get(module).$const_get(component_name, false);
|
48
|
-
|
49
|
-
if (component_type === "function" || component_type === "object") {
|
46
|
+
if (typeof constant.react_component !== 'undefined') {
|
50
47
|
component = constant.react_component;
|
51
48
|
break;
|
52
49
|
}
|
53
|
-
}
|
54
|
-
catch(err) {
|
50
|
+
} catch(err) {
|
55
51
|
component = null;
|
56
52
|
}
|
57
53
|
}
|
54
|
+
if (!component) {
|
55
|
+
try {
|
56
|
+
constant = Opal.Object.$const_get(component_name);
|
57
|
+
if (typeof constant.react_component !== 'undefined') {
|
58
|
+
component = constant.react_component;
|
59
|
+
}
|
60
|
+
} catch(err) {
|
61
|
+
component = null
|
62
|
+
}
|
63
|
+
}
|
58
64
|
}
|
59
65
|
if (component) {
|
60
|
-
|
61
|
-
var last_arg = args[args.length - 1];
|
62
|
-
if (typeof last_arg === 'string' || last_arg instanceof String) {
|
63
|
-
if (args.length === 1) { Opal.React.internal_render(component, null, last_arg, null); }
|
64
|
-
else { Opal.React.internal_render(component, args[0], last_arg, null); }
|
65
|
-
} else { Opal.React.internal_render(component, args[0], null, block); }
|
66
|
-
} else { Opal.React.internal_render(component, null, null, block); }
|
66
|
+
Opal.React.internal_prepare_args_and_render(component, args, block);
|
67
67
|
} else {
|
68
68
|
return #{_react_component_resolution_original_method_missing(component_name, *args, block)};
|
69
69
|
}
|
70
70
|
}
|
71
71
|
end
|
72
|
-
|
73
72
|
end
|
74
73
|
end
|
75
74
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module React
|
2
|
+
module Component
|
3
|
+
class Styles
|
4
|
+
def initialize(native)
|
5
|
+
@native = native
|
6
|
+
end
|
7
|
+
|
8
|
+
def method_missing(prop, *args, &block)
|
9
|
+
%x{
|
10
|
+
if (typeof #@native[prop] === 'undefined') {
|
11
|
+
return #{nil};
|
12
|
+
} else {
|
13
|
+
return #@native[prop];
|
14
|
+
}
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_n
|
19
|
+
@native
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module React
|
2
|
+
module FunctionComponent
|
3
|
+
module API
|
4
|
+
attr_accessor :props
|
5
|
+
|
6
|
+
def initialize(props)
|
7
|
+
@props = ::React::Component::Props.new(props)
|
8
|
+
end
|
9
|
+
|
10
|
+
def use_callback(deps, &block)
|
11
|
+
%x{
|
12
|
+
Opal.global.React.useCallback(function() {
|
13
|
+
#{block.call}
|
14
|
+
}, deps);
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def use_context(context)
|
19
|
+
`(typeof context.$is_wrapped_context !== 'undefined')` ? context.to_n : context
|
20
|
+
`Opal.global.React.useContext(native_context)`
|
21
|
+
end
|
22
|
+
|
23
|
+
def use_debug_value(value)
|
24
|
+
`Opal.global.React.useDebugValue(value)`
|
25
|
+
end
|
26
|
+
|
27
|
+
def use_effect(&block)
|
28
|
+
%x{
|
29
|
+
Opal.global.React.useEffect(function() {
|
30
|
+
#{block.call}
|
31
|
+
});
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def use_imperative_handle(ref, *deps, &block)
|
36
|
+
native_ref = `(typeof ref.$is_wrapped_ref !== 'undefined')` ? ref.to_n : ref
|
37
|
+
%x{
|
38
|
+
Opal.global.React.useImperativeHandle(native_ref, function() {
|
39
|
+
#{block.call}
|
40
|
+
}, deps);
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
def use_layout_effect(&block)
|
45
|
+
%x{
|
46
|
+
Opal.global.React.useLayoutEffect(function() {
|
47
|
+
#{block.call}
|
48
|
+
});
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
def use_memo(*deps, &block)
|
53
|
+
%x{
|
54
|
+
Opal.global.React.useMemo(function() {
|
55
|
+
#{block.call}
|
56
|
+
}, deps);
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def use_reducer(inital_state, &block)
|
61
|
+
state = nil
|
62
|
+
dispatcher = nil
|
63
|
+
%x{
|
64
|
+
[state, dispatcher] = Opal.global.React.useReducer(function(state, action) {
|
65
|
+
#{block.call(state, action)}
|
66
|
+
}, initial_state);
|
67
|
+
}
|
68
|
+
[state, proc { |arg| `dispatcher(arg)` }]
|
69
|
+
end
|
70
|
+
|
71
|
+
def use_ref(initial_value)
|
72
|
+
React::Ref.new(`Opal.global.React.useRef(initial_value)`)
|
73
|
+
end
|
74
|
+
|
75
|
+
def use_state(initial_value)
|
76
|
+
initial = nil
|
77
|
+
setter = nil
|
78
|
+
`[initial, setter] = Opal.global.React.useState(initial_value);`
|
79
|
+
[initial, proc { |arg| `setter(arg)` }]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|