mAAdhaTTah/brookjs

View on GitHub
packages/brookjs-silt/src/RootJunction.tsx

Summary

Maintainability
A
0 mins
Test Coverage
import React from 'react';
import Kefir, { Subscription, Pool } from 'kefir';
import { Action } from 'redux';
import { Maybe } from 'brookjs-types';
import { Provider, Consumer } from './context';

type Props<A> = {
  root$?: (p: Pool<A, never>) => Maybe<Subscription>;
  children: React.ReactNode;
};

export class RootJunction<A extends Action> extends React.Component<Props<A>> {
  childRoot$: Pool<A, never> = Kefir.pool();
  sub?: Maybe<Subscription>;
  parentRoot$?: Maybe<Pool<A, never>>;

  unplug() {
    this.parentRoot$?.unplug(this.childRoot$);
  }

  componentDidMount() {
    this.sub = this.props.root$?.(this.childRoot$);
  }

  componentDidUpdate(prevProps: Props<A>) {
    if (this.props.root$ !== prevProps.root$) {
      this.sub?.unsubscribe();
      this.sub = this.props.root$?.(this.childRoot$);
    }
  }

  componentWillUnmount() {
    this.sub?.unsubscribe();
  }

  render() {
    return (
      <Consumer>
        {parentRoot$ => {
          if (parentRoot$ != null) {
            if (this.parentRoot$ !== parentRoot$) {
              this.unplug();
              // @TODO(mAAdhaTTah) Constraint subtype issue
              this.parentRoot$ = parentRoot$.plug(this.childRoot$) as any;
            }
          }

          return (
            <Provider value={this.childRoot$}>{this.props.children}</Provider>
          );
        }}
      </Consumer>
    );
  }
}