Skip to content

Instantly share code, notes, and snippets.

@EloB
Created August 28, 2017 14:40
Show Gist options
  • Save EloB/426e51f2d69fd32ba19caa19c71d373f to your computer and use it in GitHub Desktop.
Save EloB/426e51f2d69fd32ba19caa19c71d373f to your computer and use it in GitHub Desktop.
RxComponent
import { Component, Children } from 'react';
import { ReplaySubject, Subject } from 'rxjs';
class RxComponent extends Component {
state = {
component: null,
};
componentWillMount() {
this.props$.next(this.props);
this.subscription = this.clientMounted$
.ignoreElements()
.merge(this.engine())
.subscribe(component => this.setState({ component }));
}
componentDidMount() {
this.didMountSubject.next(true);
}
componentWillReceiveProps(props) {
this.props$.next(props);
}
shouldComponentUpdate(nextProps, nextState) {
return this.state.component !== nextState.component;
}
componentWillUnmount() {
this.subscription.unsubscribe();
}
engine() { // eslint-disable-line
throw new Error('Should be implemented');
}
props$ = new ReplaySubject(1);
didMountSubject = new Subject();
clientMounted$ = this.didMountSubject
.startWith(false)
.publishReplay(1)
.refCount();
render() {
return this.state.component ? Children.only(this.state.component) : null;
}
}
export default RxComponent;
@EloB
Copy link
Author

EloB commented Aug 28, 2017

Simple use:

class MyComponent extends RxComponent {
  engine() {
    return this.props$
      .map(props => (
        <div>Hello ${props.name}</div>
      ));
  }
}

Advanced use:

class MyComponent extends RxComponent {
  engine() {
    return Observable
      .merge(addYourObservablesHereThatShouldAffectRender())
      .ignoreElements()
      .merge(this.props$)
      .map(props => (
        <div>Hello ${props.name}</div>
      ));
  }
}

Simple hoc:

const withSomething = (value) => (ComposedComponent) => class WithSomething extends RxComponent {
  engine() {
    return this.props$.map((props) => <ComposedComponent {...props} something={value} />);
  }
};

// Usage
withSomething("hello world")(SomeComponent);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment