Class: React::State
- Inherits:
-
Object
- Object
- React::State
- Defined in:
- lib/react/state.rb
Constant Summary collapse
- ALWAYS_UPDATE_STATE_AFTER_RENDER =
if on server then we don’t wait to update the state
Hyperloop.on_client?
Class Attribute Summary collapse
-
.current_observer ⇒ Object
readonly
Returns the value of attribute current_observer.
Class Method Summary collapse
- .bulk_update ⇒ Object
- .get_state(object, name, current_observer = @current_observer) ⇒ Object
- .has_observers?(object, name) ⇒ Boolean
-
.initialize_states(object, initial_values) ⇒ Object
initialize objects’ name/value pairs.
- .is_observing?(object, name, current_observer) ⇒ Boolean
-
.remove ⇒ Object
call after component is unmounted.
-
.set_state(object, name, value, delay = ALWAYS_UPDATE_STATE_AFTER_RENDER) ⇒ Object
ReactDOM.unstable_batchedUpdates does not seem to improve things here, ill leave it here commented for reference and later investigation if ‘ReactDOM.unstable_batchedUpdates !== undefined` %x{ ReactDOM.unstable_batchedUpdates(function(){ #{ |observer, args| observer.update_react_js_state(*args) } }); } else # run the other one.
- .set_state2(object, name, value, updates, exclusions = nil) ⇒ Object
-
.set_state_context_to(observer, rendering = nil) ⇒ Object
wrap all execution that may set or get states in a block so we know which observer is executing.
- .states ⇒ Object
-
.update_states_to_observe(current_observer = @current_observer) ⇒ Object
should be called after the last after_render callback, currently called after components render method.
- .will_be_observing?(object, name, current_observer) ⇒ Boolean
Class Attribute Details
.current_observer ⇒ Object (readonly)
Returns the value of attribute current_observer.
8 9 10 |
# File 'lib/react/state.rb', line 8 def current_observer @current_observer end |
Class Method Details
.bulk_update ⇒ Object
14 15 16 17 18 19 20 |
# File 'lib/react/state.rb', line 14 def bulk_update saved_bulk_update_flag = @bulk_update_flag @bulk_update_flag = true yield ensure @bulk_update_flag = saved_bulk_update_flag end |
.get_state(object, name, current_observer = @current_observer) ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/react/state.rb', line 38 def get_state(object, name, current_observer = @current_observer) # get current value of name for object, remember that the current object depends on this state, # current observer can be overriden with last param if current_observer && !new_observers[current_observer][object].include?(name) new_observers[current_observer][object] << name end if @delayed_updates && @delayed_updates[object][name] @delayed_updates[object][name][1] << current_observer end states[object][name] end |
.has_observers?(object, name) ⇒ Boolean
10 11 12 |
# File 'lib/react/state.rb', line 10 def has_observers?(object, name) !observers_by_name[object][name].empty? end |
.initialize_states(object, initial_values) ⇒ Object
initialize objects’ name/value pairs
34 35 36 |
# File 'lib/react/state.rb', line 34 def initialize_states(object, initial_values) # initialize objects' name/value pairs states[object].merge!(initial_values || {}) end |
.is_observing?(object, name, current_observer) ⇒ Boolean
89 90 91 |
# File 'lib/react/state.rb', line 89 def is_observing?(object, name, current_observer) current_observer && observers_by_name[object][name].include?(current_observer) end |
.remove ⇒ Object
call after component is unmounted
109 110 111 112 113 114 115 116 117 |
# File 'lib/react/state.rb', line 109 def remove # call after component is unmounted raise "remove called outside of watch block" unless @current_observer current_observers[@current_observer].each do |object, names| names.each do |name| observers_by_name[object][name].delete(@current_observer) end end current_observers.delete(@current_observer) end |
.set_state(object, name, value, delay = ALWAYS_UPDATE_STATE_AFTER_RENDER) ⇒ Object
ReactDOM.unstable_batchedUpdates does not seem to improve things here, ill leave it here commented for reference and later investigation if ‘ReactDOM.unstable_batchedUpdates !== undefined`
%x{
ReactDOM.unstable_batchedUpdates(function(){
#{updates.each { |observer, args| observer.update_react_js_state(*args) }}
});
}
else # run the other one
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/react/state.rb', line 59 def set_state(object, name, value, delay=ALWAYS_UPDATE_STATE_AFTER_RENDER) states[object][name] = value delay = false if object.respond_to?(:set_state_synchronously?) && object.set_state_synchronously? if delay || @bulk_update_flag @delayed_updates ||= Hash.new { |h, k| h[k] = {} } @delayed_updates[object][name] = [value, Set.new] @delayed_updater ||= after(0.001) do delayed_updates = @delayed_updates @delayed_updates = Hash.new { |h, k| h[k] = {} } # could this be nil??? @delayed_updater = nil updates = Hash.new { |hash, key| hash[key] = Array.new } delayed_updates.each do |object, name_hash| name_hash.each do |name, value_and_set| set_state2(object, name, value_and_set[0], updates, value_and_set[1]) end end updates.each { |observer, args| observer.update_react_js_state(*args) } end elsif @rendering_level == 0 updates = Hash.new { |hash, key| hash[key] = Array.new } set_state2(object, name, value, updates) updates.each { |observer, args| observer.update_react_js_state(*args) } end value end |
.set_state2(object, name, value, updates, exclusions = nil) ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/react/state.rb', line 22 def set_state2(object, name, value, updates, exclusions = nil) # set object's name state to value, tell all observers it has changed. # Observers must implement update_react_js_state object_needs_notification = object.respond_to?(:update_react_js_state) observers_by_name[object][name].dup.each do |observer| next if exclusions && exclusions.include?(observer) updates[observer] += [object, name, value] object_needs_notification = false if object == observer end updates[object] += [nil, name, value] if object_needs_notification end |
.set_state_context_to(observer, rendering = nil) ⇒ Object
wrap all execution that may set or get states in a block so we know which observer is executing
119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/react/state.rb', line 119 def set_state_context_to(observer, rendering = nil) # wrap all execution that may set or get states in a block so we know which observer is executing saved_current_observer = @current_observer @current_observer = observer @rendering_level += 1 if rendering return_value = yield return_value ensure @current_observer = saved_current_observer @rendering_level -= 1 if rendering return_value end |
.states ⇒ Object
131 132 133 |
# File 'lib/react/state.rb', line 131 def states @states ||= Hash.new { |h, k| h[k] = {} } end |
.update_states_to_observe(current_observer = @current_observer) ⇒ Object
should be called after the last after_render callback, currently called after components render method
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/react/state.rb', line 93 def update_states_to_observe(current_observer = @current_observer) # should be called after the last after_render callback, currently called after components render method raise "update_states_to_observer called outside of watch block" unless current_observer current_observers[current_observer].each do |object, names| names.each do |name| observers_by_name[object][name].delete(current_observer) end end observers = current_observers[current_observer] = new_observers[current_observer] new_observers.delete(current_observer) observers.each do |object, names| names.each do |name| observers_by_name[object][name] << current_observer end end end |
.will_be_observing?(object, name, current_observer) ⇒ Boolean
85 86 87 |
# File 'lib/react/state.rb', line 85 def will_be_observing?(object, name, current_observer) current_observer && new_observers[current_observer][object].include?(name) end |