lequanghuylc
2/23/2018 - 7:46 PM

BaseComponen that can give you more control over React Component

BaseComponen that can give you more control over React Component

import { Component } from "react";
import PropTypes from "prop-types";

export default class BaseComponent extends Component {
  
  static propTypes = {
    id: PropTypes.string
  }

  static States = {};

  static getId = id => BaseComponent.States[id];

  static setStateAllInstances = async objOrFunc => {
    let promiseArr = [];
    for ( let id in BaseComponent.States) {
      promiseArr.push(BaseComponent.States[id].setState(objOrFunc));
    }
    await Promise.all(promiseArr);
  }

  _setupStateById = () => {
    if (!this.props.id) return;
    const setState = obj => this.set(obj);
    const state = () => this.state;
    BaseComponent.States[this.props.id] = {
      setState: setState,
      state: state
    };
  };

  mounted = false;

  set = objOrFunc => this.mounted === false
      ? Promise.resolve()
      : new Promise((resolve, reject) => {
          try {
            this.setState(objOrFunc, () => {
              resolve();
            });
          } catch (err) {
            reject(err);
          }
        });

  componentWillMount() {
    this._setupStateById();
    typeof this.willMount === "function" && this.willMount();
  }

  componentDidMount() {
    this.mounted = true;
    typeof this.didMount === "function" && this.didMount();
  }

  componentWillUnmount() {
    this.mounted = false;
    typeof this.willUnmount === "function" && this.willUnmount();
    delete BaseComponent.States[this.props.id];
  }
}

/*
  Assume you have a component (that extends BaseComponent):
  <ContainerA id="cA" />
  if you want to get state of this ContainerA: do the following
  ```
    import ContainerA from "./somewhere";
    console.log(ContainerA.getId("cA").state())
  ```
  if you want to set state of this ContainerA: do the following
  ```
    import ContainerA from "./somewhere";
    ContainerA.getId("cA").setState({ foo: "bar" })
  ```
*/