How to relate the reaction state to the observed RxJS flow?

Can someone help me relate the state of React to the RxJS Observable? I liked it

componentDidMount() {
  let source = Rx.Observable.of(this.state.val)
}

The ideal result is when updating this.state.val(through this.setState(...)) source, so I can combine sourcewith another RxJS observable stream.

However, in this case, it is sourceupdated only once, even after it is this.state.valupdated, and the component is re-displayed.

// Ideal result:
this.state.val = 1
source.subscribe(val => console.log(x)) //=> 1
this.state.val = 2
source.subscribe(val => console.log(val)) //=> 2

// Real result:
this.state.val = 1
source.subscribe(val => console.log(x)) //=> 1
this.state.val = 2
source.subscribe(val => console.log(val)) //=> 1 ???WTH

Perhaps this is because it componentDidMount()is called only once during the Response. so I move sourceto componentDidUpdate(), which is called every time after rendering the component. However, the result still remains the same.

So, the question is, how do I update sourcewhen updating this.state.val?

: , , Rx.Subject

// Component file
constructor() {
  super(props)
  this.source = new Rx.Subject()
_onChangeHandler(e) {
 this.source.onNext(e.target.value)
}
componentDidMount() {
  this.source.subscribe(x => console.log(x)) // x is updated
}
render() {
  <input type='text' onChange={this._onChangeHandler} />
}
// 
+4
4

Rx.Observable.ofObjectChanges > cf. https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/ofobjectchanges.md.

:

- , , : shouldComponentUpdate, componentWillUpdate, componentDidUpdate. https://facebook.imtqy.com/react/docs/component-specs.html . , this.state.val, , .

reactjs, , .

+1

Update

, recompose mapPropsStream componentFromStream. .

const WithMouseMove = mapPropsStream((props$) => {
  const { handler: mouseMove, stream: mouseMove$ } = createEventHandler();

  const mousePosition$ = mouseMove$
    .startWith({ x: 0, y: 0 })
    .throttleTime(200)
    .map(e => ({ x: e.clientX, y: e.clientY }));

  return props$
    .map(props => ({ ...props, mouseMove }))
    .combineLatest(mousePosition$, (props, mousePosition) => ({ ...props, ...mousePosition }));
});

const DumbComponent = ({ x, y, mouseMove }) => (
  <div
    onMouseMove={mouseMove}
  >
    <span>{x}, {y}</span>
  </div>
);

const DumbComponentWithMouseMove = WithMouseMove(DumbComponent);

OP, rxjs5, :

class SomeComponent extends React.Component {
  constructor(props) {
    super(props);

    this.mouseMove$ = new Rx.Subject();
    this.mouseMove$.next = this.mouseMove$.next.bind(this.mouseMove$);

    this.mouseMove$
      .throttleTime(1000)
      .subscribe(idx => {
        console.log('throttled mouse move');
      });
  }

  componentWillUnmount() {
    this.mouseMove$.unsubscribe();
  }

  render() {
    return (
      <div
       onMouseMove={this.mouseMove$.next}
      />
    );
  }
}

:

  • onNext() next()
  • next mouseMove
  • componentWillUnmount hook

, , constructor hook, 1+, , next/error/complete. jsbin , .

, - , , , .

+3

, , , , . Observable.fromEvent:

class MouseOverComponent extends React.Component {

  componentDidMount() {
    this.mouseMove$ = Rx.Observable
      .fromEvent(this.mouseDiv, "mousemove")
      .throttleTime(1000)
      .subscribe(() => console.log("throttled mouse move"));

  }

  componentWillUnmount() {
    this.mouseMove$.unsubscribe();
  }

  render() {
    return (
      <div ref={(ref) => this.mouseDiv = ref}>
          Move the mouse...
      </div>
    );
  }
}


ReactDOM.render(<MouseOverComponent />, document.getElementById('app'));

codepen....

, , , , React .

+1

React RxJS:

https://medium.com/@fahad19/using-rxjs-with-react-js-part-2-streaming-props-to-component-c7792bc1f40f

It uses FrintJS and uses observea higher order component to return props as a stream:

import React from 'react';
import { Observable } from 'rxjs';
import { observe } from 'frint-react';

function MyComponent(props) {
  return <p>Interval: {props.interval}</p>;
}

export default observe(function () {
  // return an Observable emitting a props-compatible object here
  return Observable.interval(1000)
    .map(x => ({ interval: x }));
})(MyComponent);
0
source

Source: https://habr.com/ru/post/1616000/


All Articles