All Downloads are FREE. Search and download functionalities are using the official Maven repository.

react4j.core.NativeAdapterComponent Maven / Gradle / Ivy

There is a newer version: 0.02
Show newest version
package react4j.core;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import jsinterop.annotations.JsType;

/**
 * This class provides a base class that designed to forward all lifecycle methods to a target component.
 * The target component is of type {@link Component}. This class is also responsible for calling
 * {@link Component#setState(ComponentState)} before and after each call to the target component
 * if {@link ReactConfig#checkComponentStateInvariants()} returns true. This will make it possible for the
 * target component to check that the application code is correctly interacting with the React component
 * framework. In production builds it is expected that the method calls will be inlined and the checks will
 * be optimized away, having no significant performance impact.
 */
@JsType
public abstract class NativeAdapterComponent<
  P extends BaseProps,
  S extends BaseState,
  C extends Component
  >
  extends NativeComponent
{
  /**
   * The target component that all lifecycle methods are forwarded to.
   */
  private final C _component;

  /**
   * Create a component that designed to delegate to a target component.
   *
   * @param props the initial props.
   */
  protected NativeAdapterComponent( @Nonnull final P props )
  {
    super( props );
    _component = createComponent();
    _component.bindComponent( this );

    componentInitialize();
  }

  /**
   * Template method that actually creates the target component.
   *
   * @return a new instance of the target component.
   */
  protected abstract C createComponent();

  /**
   * Initialize the target component.
   */
  private void componentInitialize()
  {
    if ( ReactConfig.checkComponentStateInvariants() )
    {
      _component.setPhase( ComponentPhase.INITIALIZING );
      _component.setState( ComponentState.INITIAL );
    }
    try
    {
      _component.componentInitialize();
    }
    finally
    {
      if ( ReactConfig.checkComponentStateInvariants() )
      {
        _component.setState( ComponentState.UNKNOWN );
        _component.setPhase( ComponentPhase.MOUNTING );
      }
    }
  }

  /**
   * Call render on the target component.
   *
   * @return the react component.
   * @see Component#render()
   */
  @Nullable
  public final ReactElement render()
  {
    if ( ReactConfig.checkComponentStateInvariants() )
    {
      _component.setState( ComponentState.RENDER );
    }
    try
    {
      return _component.render();
    }
    finally
    {
      if ( ReactConfig.checkComponentStateInvariants() )
      {
        _component.setState( ComponentState.UNKNOWN );
      }
    }
  }

  /**
   * Call componentDidMount on the target component.
   * It is expected that the subclass will implement a public method componentDidMount() that
   * delegates to this method to perform the work.
   *
   * @see Component#componentDidMount()
   */
  protected final void performComponentDidMount()
  {
    if ( ReactConfig.checkComponentStateInvariants() )
    {
      _component.setState( ComponentState.COMPONENT_DID_MOUNT );
    }
    try
    {
      _component.componentDidMount();
    }
    finally
    {
      if ( ReactConfig.checkComponentStateInvariants() )
      {
        _component.setState( ComponentState.UNKNOWN );
        _component.setPhase( ComponentPhase.UPDATING );
      }
    }
  }

  /**
   * Call componentWillMount on the target component.
   * It is expected that the subclass will implement a public method componentWillMount() that
   * delegates to this method to perform the work.
   *
   * @see Component#componentWillMount()
   */
  protected final void performComponentWillMount()
  {
    if ( ReactConfig.checkComponentStateInvariants() )
    {
      _component.setState( ComponentState.COMPONENT_WILL_MOUNT );
    }
    try
    {
      _component.componentWillMount();
    }
    finally
    {
      if ( ReactConfig.checkComponentStateInvariants() )
      {
        _component.setState( ComponentState.UNKNOWN );
      }
    }
  }

  /**
   * Call componentWillUnmount on the target component.
   * It is expected that the subclass will implement a public method componentWillUnmount() that
   * delegates to this method to perform the work.
   *
   * @see Component#componentWillUnmount()
   */
  protected final void performComponentWillUnmount()
  {
    if ( ReactConfig.checkComponentStateInvariants() )
    {
      _component.setPhase( ComponentPhase.UNMOUNTING );
      _component.setState( ComponentState.COMPONENT_WILL_UNMOUNT );
    }
    try
    {
      _component.componentWillUnmount();
    }
    finally
    {
      if ( ReactConfig.checkComponentStateInvariants() )
      {
        _component.setState( ComponentState.UNKNOWN );
      }
    }
  }

  /**
   * Call componentWillUpdate on the target component.
   * It is expected that the subclass will implement a public method componentWillUpdate() that
   * delegates to this method to perform the work.
   *
   * @param nextProps the props.
   * @param nextState the state.
   * @see Component#componentWillUpdate(BaseProps, BaseState)
   */
  protected final void performComponentWillUpdate( @Nonnull final P nextProps, @Nonnull final S nextState )
  {
    if ( ReactConfig.checkComponentStateInvariants() )
    {
      _component.setState( ComponentState.COMPONENT_WILL_UPDATE );
    }
    try
    {
      _component.componentWillUpdate( nextProps, nextState );
    }
    finally
    {
      if ( ReactConfig.checkComponentStateInvariants() )
      {
        _component.setState( ComponentState.UNKNOWN );
      }
    }
  }

  /**
   * Call shouldComponentUpdate on the target component.
   * It is expected that the subclass will implement a public method shouldComponentUpdate() that
   * delegates to this method to perform the work.
   *
   * @param nextProps the props.
   * @param nextState the state.
   * @see Component#shouldComponentUpdate(BaseProps, BaseState)
   */
  protected final boolean performShouldComponentUpdate( @Nonnull final P nextProps, @Nonnull final S nextState )
  {
    if ( ReactConfig.checkComponentStateInvariants() )
    {
      _component.setState( ComponentState.SHOULD_COMPONENT_UPDATE );
    }
    try
    {
      return _component.shouldComponentUpdate( nextProps, nextState );
    }
    finally
    {
      if ( ReactConfig.checkComponentStateInvariants() )
      {
        _component.setState( ComponentState.UNKNOWN );
      }
    }
  }

  /**
   * Call componentWillReceiveProps on the target component.
   * It is expected that the subclass will implement a public method componentWillReceiveProps() that
   * delegates to this method to perform the work.
   *
   * @param nextProps the props.
   * @see Component#componentWillReceiveProps(BaseProps)
   */
  protected final void performComponentWillReceiveProps( @Nonnull final P nextProps )
  {
    if ( ReactConfig.checkComponentStateInvariants() )
    {
      _component.setState( ComponentState.COMPONENT_WILL_RECEIVE_PROPS );
    }
    try
    {
      _component.componentWillReceiveProps( nextProps );
    }
    finally
    {
      if ( ReactConfig.checkComponentStateInvariants() )
      {
        _component.setState( ComponentState.UNKNOWN );
      }
    }
  }

  /**
   * Call componentDidUpdate on the target component.
   * It is expected that the subclass will implement a public method componentDidUpdate() that
   * delegates to this method to perform the work.
   *
   * @param nextProps the props.
   * @param nextState the state.
   * @see Component#componentDidUpdate(BaseProps, BaseState)
   */
  protected final void performComponentDidUpdate( @Nonnull final P nextProps, @Nonnull final S nextState )
  {
    if ( ReactConfig.checkComponentStateInvariants() )
    {
      _component.setState( ComponentState.COMPONENT_DID_UPDATE );
    }
    try
    {
      _component.componentDidUpdate( nextProps, nextState );
    }
    finally
    {
      if ( ReactConfig.checkComponentStateInvariants() )
      {
        _component.setState( ComponentState.UNKNOWN );
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy