class React::State
Constants
- ALWAYS_UPDATE_STATE_AFTER_RENDER
Attributes
current_observer[R]
Public Class Methods
bulk_update() { || ... }
click to toggle source
# 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)
click to toggle source
# File lib/react/state.rb, line 50 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)
click to toggle source
# File lib/react/state.rb, line 10 def has_observers?(object, name) !observers_by_name[object][name].empty? end
ignore_bulk_updates(*args) { |*args| ... }
click to toggle source
React
already will batch together updates inside of event handlers so we don't have to, and having Hyperstack batch them outside of the event handler causes INPUT/TEXT/SELECT s not to work properly. This method is called by the Component event wrapper.
# File lib/react/state.rb, line 26 def ignore_bulk_updates(*args) saved_ignore_bulk_update_flag = @ignore_bulk_update_flag @ignore_bulk_update_flag = true yield(*args) ensure @ignore_bulk_update_flag = saved_ignore_bulk_update_flag end
initialize_states(object, initial_values)
click to toggle source
# File lib/react/state.rb, line 46 def initialize_states(object, initial_values) # initialize objects' name/value pairs states[object].merge!(initial_values || {}) end
is_observing?(object, name, current_observer)
click to toggle source
# File lib/react/state.rb, line 103 def is_observing?(object, name, current_observer) current_observer && observers_by_name[object][name].include?(current_observer) end
remove()
click to toggle source
# File lib/react/state.rb, line 123 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)
click to toggle source
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
# File lib/react/state.rb, line 71 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 !@ignore_bulk_update_flag && (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 ensure 'Disabling JIT for Safari bug' end
set_state2(object, name, value, updates, exclusions = nil)
click to toggle source
# File lib/react/state.rb, line 34 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) { || ... }
click to toggle source
# File lib/react/state.rb, line 133 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()
click to toggle source
# File lib/react/state.rb, line 145 def states @states ||= Hash.new { |h, k| h[k] = {} } end
update_states_to_observe(current_observer = @current_observer)
click to toggle source
# File lib/react/state.rb, line 107 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)
click to toggle source
# File lib/react/state.rb, line 99 def will_be_observing?(object, name, current_observer) current_observer && new_observers[current_observer][object].include?(name) end