fdecampredon/rx-react

Open to including ES7 decorators as an alternative to throwing everything in componentWillMount?

garbles opened this issue · 3 comments

This library looks fantastic; though I wonder if including ES7 decorators would make digesting components a little easier (as Babel supports them). Here's what I mean...

// instead of this
var Button = React.createClass({
  componentWillMount: function () {
    this.buttonClicked = FuncSubject.create();

    this.buttonClicked.subscribe(function (event) {
      alert('button clicked');
    })
  },
  render: function() {
    return <button onClick={this.buttonClicked} />
  }
});

// do this
var Button = React.createClass({
  @stream
  buttonClicked (eventStream) {
    eventStream.subscribe(function (event) {
      alert('button clicked');
    });
  },

  render: function() {
    return <button onClick={this.buttonClicked} />
  }
});

If this is a good idea, I will submit a PR for it. As far as I can tell it's just a small wrapper around the FuncSubject you've already written. 😄

Your proposal could be interesting, however when I think a bit about it there is mainly 2 use case for event handling :

  • using event handling in a stream that will be composed into the state stream mixin
  • calling an external function (props callback action etc)

for the first case you can easily alredy use the stage 0 class property proposal :

import { Component, FuncSubject } from 'rx-react';
class MyComponent  extends Component {
  buttonClicked = FuncSubject.create();
  getStateStream() {
   return this.buttonClicked.map(buttonClicked => ({ active }));
  }
  render() {
    <button onClick={this.buttonClicked} className={this.props.active ? 'active' : ''} />
  }
}

For the second case you generally don't use FuncSubject but classic event handler:

import { doSomething } from 'my-action';
class MyComponent  extends Component {
  buttonClicked() {
    doSomething();
  }
  render() {
    <button onClick={() => this.buttonClicked() } >
  }
} 

Could you please show me an use-case were your proposal provide a simpler solution ?

Ah good point. 😅

I suppose a scenario where it may be beneficial is one where the doSomething in your example is also an observer/subject rather than just a function (though calling doSomething.onNext isn't difficult either).

  // ...
  buttonClicked (eventStream) {
    eventStream
      .map(event => event.target.value)
      .subscribe(doSomething);
  }

Honestly after thinking about it I don't really see the benefit, If you find better use case feel free to comment and I might reopen.