hyper-react icon indicating copy to clipboard operation
hyper-react copied to clipboard

deprecate Observables

Open catmando opened this issue 9 years ago • 5 comments

Observables should be deprecated. This was largely a ruby-ized version of the old react.js links. There are better patterns now (i.e. events or stores)

(@zetachang - there is a deprecation method available... also under the hood the observable class is still used I believe, so this just a matter of pulling any special handling in the param method.)

catmando avatar Sep 14 '16 13:09 catmando

Actually I am not quite familiar with the Observable code base, so here is a first scan of discovery.

So we are going to deprecate the following APIs,

  1. param :foo, type: React::Observable
  2. state.foo! when used without any argument. (state.foo! new_foo should work as before)

zetachang avatar Oct 13 '16 10:10 zetachang

Hmmm...

Okay well point 2 is definitely NO

being able to say state.foo! without params is vital because it allows you to do this:

state.foo! << 'new item'

The value returned by state.foo! (without params) is indeed an observable object, that will update the state whenever it sees action applied to that object. Its basically an alternative to immutable objects. Instead of forcing everything to be immutable, it allows mutations on state values that can be recorded and notify react.

param :foo, type: React::Observable is a special case that allows the observable to be passed along to a component, and then within that component you can say

  • params.foo (meaning get current value of foo, with no state update), or
  • params.foo!(...new value...) (meaning update the observers value of value, including notification of whoever owns the underlying state, and
  • params.foo! (meaning return the observable itself)

Now that I am thinking about it there is little point in removing the special observable params handling, it may not be used often, but it costs almost nothing, so why not leave it?

catmando avatar Oct 15 '16 14:10 catmando

suggest we just close...

catmando avatar Oct 15 '16 14:10 catmando

Now I got the point. And I think this is related to https://github.com/reactrb/reactrb/issues/136, right?

So instead of deprecating this, maybe we could extract this as a separate module first,

  1. Basic StateWrapper will only allow method like state.attr & state.attr = new_value
  2. All interpretation of state.attr! will be extracted as something like ObservableHelpers and could be included by default.

Also some discovery to share, there is some similar JS libs like Baobab or react-cursor which I found similar to the approach we are using.

zetachang avatar Oct 20 '16 08:10 zetachang

Yes.. frankly I think reactrb is way ahead on this... its simple easy and elegant.

If we wanted to we could take one step further I think:

We could build new versions of all the opal standard libraries where any mutations call react set state.

class Array
  attr_accessor :observer
  alias_method "old_push", "push"
  def push(*args)
    old_push.tap { |x| observer.call(x) if observer }
  end
end

my_array = [1, 2, 3]
puts my_array
my_array.observer = lambda { |*args| puts "observed #{args}"}
my_array.push 4
puts my_array

Now we would simply on assignment of any object to a state object start observing the object for mutations.

In addition we could provide some method that lets you declare which methods of a class are mutators, so you can build new classes.

Its a lot of work to get rid of remembering to do the "!" when updating a state, but it would be fun.

catmando avatar Oct 20 '16 14:10 catmando