Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I integrate rxjs observables with a plain React Component?

I am new to Rxjs and am trying to learn how to integrate it with a simple React component without any external wrapper/library. I got this working here:

const counter = new Subject()

class App extends Component {

  state = {
    number: 0
  }

  componentDidMount() {
    counter.subscribe(
      val => {
        this.setState({ number: this.state.number + val })
      }
    )
  }

  increment = () => {
    counter.next(+1)
  }

  decrement = () => {
    counter.next(-1)

  }


  render() {
    return (
      <div style={styles}>
        Current number {this.state.number} 
        <br /> <br />
        <button onClick={this.increment}>Plus</button>
        <button onClick={this.decrement}>Minus</button>
      </div>
    )
  }

https://codesandbox.io/s/02j7qm2xw

I trouble is that this uses Subjects which is a known anti-pattern according to experts like Ben Lesh: https://medium.com/@benlesh/on-the-subject-of-subjects-in-rxjs-2b08b7198b93

I tried doing this:

var counter = Observable.create(function (observer) {
  // Yield a single value and complete
  observer.next(0);

  // Any cleanup logic might go here
  return function () {
    console.log('disposed');
  }
});

class App extends Component {

  state = {
    number: 0
  }

  componentDidMount() {
    counter.subscribe(
      val => {
        this.setState({ number: this.state.number + val })
      }
    )
  }

  increment = () => {
    counter.next(+1)
  }

  decrement = () => {
    counter.next(-1)

  }


  // - render

}

But this fails with the error: counter.next is not a function

So How would I use new Observable() or Observable.create()and use it to setState with a plain React component?

like image 875
Amit Erandole Avatar asked Oct 11 '17 04:10

Amit Erandole


People also ask

Can we use RxJS With React?

Compared to other alternatives like Redux, I've found the use of RxJS and Hooks to be a really effective and straightforward way to manage state in React applications.

How do I use Behaviorsubject in React?

You can do it on the component itself, or on it's parent and pass the value to it as props. A good practice is to handle the unsubscription on the componentWillUnmount event using the takeUntil operator and a Subject: unmount$ = new Subject() //component class property componentDidMount() { //if using rxjs 6: window.

How do RxJS Observables work?

Observables are data source wrappers and then the observer executes some instructions when there is a new value or a change in data values. The Observable is connected to the observer who does the execution through subscription, with a subscribe method the observer connects to the observable to execute a code block.


1 Answers

Because .next() is an Observer's method, NOT Observables.

The reason why Subject works simply because Subject itself is both an observer and an observable. When you call subject.next(), you are simply just updating the observable part, and notify all the observers about the change.

It can be quite confusing sometimes when comes to Observable and Observers. To make it simple, think of this way: Observable is someone who produces the data, a.k.a. data producers; while Observer is someone who consume the data, a.k.a. data consumer. In a simple analogy, consumer eats what is produced. For the same token, Observer(consumer) observes(eats) the observable (produced).

In your context (or at least React/Redux paradigm), Subject works better. That is because Subject has state. It keep tracks of the value over the production of data (job of the Observable). Every time the observable (the one inside Subject) changes, or update, any observers that subscribes to the Subject will get notified. See the pattern similar to redux here? Every time your redux store is updated, your view gets notified (and hence updated). In fact, if you are very used to reactive programming, you can eliminate the use of redux store completely, and fully replace them by Subjects and/or BehaviourSubjects.

For the post from Ben Lesh, he is merely stating this: Always use an Observable if possible, only use Subject when it is really needed. In that particular post, he is stating that a click event can just be an Observable; using Subject will be inappropriate. However, in your context, which is react/redux, using Subject is fine - because the Subject is used to keep track of the state of the store, and NOT the click event handler.

TLDR:

  1. Use Subject if you want to keep track of a state of a variable
  2. .next() is Observer's method, not Observable.
like image 95
CozyAzure Avatar answered Oct 16 '22 01:10

CozyAzure