function create()

in src/container/FluxContainer.js [103:189]


function create<DefaultProps, Props, State>(
  Base: ReactClass<Props>,
  options?: ?Options,
): ReactClass<Props> {
  enforceInterface(Base);

  // Construct the options using default, override with user values as necessary.
  const realOptions = {
    ...DEFAULT_OPTIONS,
    ...(options || {}),
  };

  const getState = (state, maybeProps, maybeContext) => {
    const props = realOptions.withProps ? maybeProps : undefined;
    const context = realOptions.withContext ? maybeContext : undefined;
    return Base.calculateState(state, props, context);
  };

  const getStores = (maybeProps, maybeContext) => {
    const props = realOptions.withProps ? maybeProps : undefined;
    const context = realOptions.withContext ? maybeContext : undefined;
    return Base.getStores(props, context);
  };

  // Build the container class.
  class ContainerClass extends Base {
    _fluxContainerSubscriptions: FluxContainerSubscriptions;

    constructor(props: Props, context: any) {
      super(props, context);
      this._fluxContainerSubscriptions = new FluxContainerSubscriptions();
      this._fluxContainerSubscriptions.setStores(getStores(props, context));
      this._fluxContainerSubscriptions.addListener(() => {
        this.setState(
          (prevState, currentProps) => getState(
            prevState,
            currentProps,
            context,
          ),
        );
      });
      const calculatedState = getState(undefined, props, context);
      this.state = {
        ...(this.state || {}),
        ...calculatedState,
      };
    }

    UNSAFE_componentWillReceiveProps(nextProps: any, nextContext: any): void {
      if (super.UNSAFE_componentWillReceiveProps) {
        super.UNSAFE_componentWillReceiveProps(nextProps, nextContext);
      }

      if (super.componentWillReceiveProps) {
        super.componentWillReceiveProps(nextProps, nextContext);
      }

      if (realOptions.withProps || realOptions.withContext) {
        // Update both stores and state.
        this._fluxContainerSubscriptions.setStores(
          getStores(nextProps, nextContext),
        );
        this.setState(prevState => getState(prevState, nextProps, nextContext));
      }
    }

    componentWillUnmount() {
      if (super.componentWillUnmount) {
        super.componentWillUnmount();
      }

      this._fluxContainerSubscriptions.reset();
    }
  }

  // Make sure we override shouldComponentUpdate only if the pure option is
  // specified. We can't override this above because we don't want to override
  // the default behavior on accident. Super works weird with react ES6 classes.
  const container = realOptions.pure
    ? createPureComponent(ContainerClass)
    : ContainerClass;

  // Update the name of the container before returning
  const componentName = Base.displayName || Base.name;
  container.displayName = 'FluxContainer(' + componentName + ')';
  return container;
}