Module: React::Component::NativeComponentConstructor

Defined in:
lib/react/component/native_component_constructor.rb

Class Method Summary collapse

Class Method Details

.extended(base) ⇒ Object

for should_component_update we apply ruby semantics for comparing props to do so, we convert the props to ruby hashes and then compare this makes sure, that for example rubys Nil object gets handled properly



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/react/component/native_component_constructor.rb', line 7

def self.extended(base)
  component_name = base.to_s
  %x{
    base.react_component = class extends Opal.global.React.Component {
      constructor(props) {
        super(props);
        if (base.$default_state_defined()) {
          this.state = base.$state().$to_n();
        } else {
          this.state = {};
        };
        this.__ruby_instance = base.$new(this);
        var defined_refs = #{base.defined_refs};
        for (var ref in defined_refs) {
          if (defined_refs[ref] != null) {
            this[ref] = function(element) {
              element = Opal.React.native_element_or_component_to_ruby(element);
              #{`this.__ruby_instance`.instance_exec(`element`, &`defined_refs[ref]`)}
            }
            this[ref] = this[ref].bind(this);
          } else {
            this[ref] = Opal.global.React.createRef();
          }
        }
      }
      static get displayName() {
        return #{component_name};
      }
      static set displayName(new_name) {
        // dont do anything here except returning the set value
        return new_name;
      }
      render() {
        const oper = Opal.React;
        oper.render_buffer.push([]);
        // console.log("react component pushed", oper.render_buffer, oper.render_buffer.toString());
        oper.active_components.push(this);
        let block_result = #{`this.__ruby_instance`.instance_exec(&`base.render_block`)};
        if (block_result && block_result !== nil) { oper.render_block_result(block_result); }
        // console.log("react component popping", oper.render_buffer, oper.render_buffer.toString());
        oper.active_components.pop();
        let result = oper.render_buffer.pop();
        return (result.length === 1) ? result[0] : result;
      }
      shouldComponentUpdate(next_props, next_state) {
        if (base.should_component_update_block) {
          return #{!!`this.__ruby_instance`.instance_exec(React::Component::Props.new(`{props: next_props}`), React::Component::State.new(`{state: next_state }`), &`base.should_component_update_block`)};
        }
        if (!Opal.React.props_are_equal(this.props, next_props)) { return true; }
        if (Opal.React.state_is_not_equal(this.state, next_state)) { return true; }
        return false;
      }
      validateProp(props, propName, componentName) {
        try { base.$validate_prop(propName, props[propName]) }
        catch (e) { return new Error(componentName + " Error: prop validation failed: " + e.message); }
        return null;
      }
    }
  }
end