hyperstack icon indicating copy to clipboard operation
hyperstack copied to clipboard

params which contain procs (callbacks) cause re-rerenders

Open catmando opened this issue 5 years ago • 6 comments


class Child
  include Hyperstack::Component
​
  param :do_something
​
  render do
    puts "child: @DoSomething.object_id"
  end
end
​
class Parent
  include Hyperstack::Component
​
  before_mount do
    @do_something = -> { puts "we did it" }
  end
​
  render do
    puts "parent: @do_something.object_id"
    Child(do_something: @do_something)
  end
end

the two object_id's won't match, causing the child to be rerendered everytime the parent is rendered.

Clearly something is wrapping proc params, but not clear where this is happening.

catmando avatar Dec 11 '20 18:12 catmando

on my projet I fixed this problem by redefining props_changed?

  def props_changed?(next_props)
    return true if `Object.keys(#{@__hyperstack_component_native}.props).length` != next_props.length
    props = Hash.new(`#{@__hyperstack_component_native}.props`)
    next_props.each do |k, v|
      next if v.is_a?(Proc) && props[k].is_a?(Proc)
      return true if props[k] != v
    end
    return false
  end

I am not really satisfied with Hash.new A native solution would be better but I don't know how to check if a value is a Proc in javascript

lionelchauvin avatar Dec 15 '20 12:12 lionelchauvin

@catmando Usually we do fires for this kind of callback props instead of params, right?

princejoseph avatar Dec 27 '20 08:12 princejoseph

@princejoseph yes but i think fires is just syntactic sugar ontop of the base mechanism, so the performance issue will exists regardless.

catmando avatar Dec 28 '20 22:12 catmando

More info on this from @adamcreekroad:

The problem is that some where along the line a proc object is being wrapped with an extra JS function as its being passed around this makes the proc look like a new proc object every time.

catmando avatar Dec 28 '20 22:12 catmando

@catmando ah, makes total sense. I really liked that it has a seperate fires for the component. Makes the component behaviour obvious in a glance.

princejoseph avatar Dec 29 '20 03:12 princejoseph

Note: Spec is already written, and is being skipped in component_spec.rb

catmando avatar Mar 16 '21 01:03 catmando