Class ComponentInstance<TProps>

A superset of ComponentLogic that adds support for lifecycle methods. This provides a declarative API for working with your React function component's lifecycle, a simpler alternative to the imperative approach with useEffect and/or useMemo.

Type Parameters

Hierarchy (View Summary)

Constructors

Properties

beforeMount: IVoidFunction = ...

Runs only before first render, i.e before the component instance is mounted.

It is ignored on subsequent rerenders.

PS: You can conditionally update state from here, but with certain caveats. See the React docs for more details.

onMount: AsyncAllowedEffectCallback = ...

Runs only after first render, i.e after the component instance is mounted. It is ignored on subsequent rerenders.

Should usually only be used for logic that does not directly take part in determining what to render, like synchronize your component with some external system.

A cleanup function.

Uses useEffect() under the hood.

beforeRender: () => void | object = ...

Runs before every render cycle, including the first. Useful for logic that is involved in determining what to render.

This is the ideal place to transform data for display. Return the transformed data in an object, and the object will availble as [self.templateContext](templateContext) for use in your JSX template.

PS: You can conditionally update state from here, but with certain caveats. See the React docs for more details.

onRender: AsyncAllowedEffectCallback = ...

Runs after every render cycle, including the first.

Should usually only be used for logic that does not directly take part in determining what to render, like synchronize your component with some external system.

Uses useEffect() under the hood.

Returns a cleanup function.

cleanUp: IVoidFunction = ...

Runs when the component is unmounted. It is called after the cleanup function returned by onMount.

state: TCleanState<object>

A CleanState object. Holds all of your component's state, and methods for conveniently manipulating those values. Initialiazed with the object returned from your getInitialState method.

props: TProps extends null ? EmptyObject : TProps

The props passed into your component at the time of rendering.

hooks: void | object

Values received from the hooks your component consumes. This holds the latest copy of the object returned by useHooks.

_hmrPreserveKeys: (string & {} | (keyof ComponentInstance<TProps>))[] = []

Specify custom class members to be copied over whenever the class is reinstantiated during hot module replacement.

Oore handles HMR by recreating the class instance with the updated code whenever there is a file change. Your component is then rerendered so that event handlers now point to the new functions.

For this to work well, your component's state needs to be preserved, so it is copied over from the old instance, to the newly created one. This includes state, props by default, but you can extend it to include more properties if there are values your component expects to be persistent.

In most case, any values you wish to preserve should be created React.useRef.

// In useHooks method:
this.inputId = useRef(inputId);
// And access anywhere with:
this.inputId.current;

If you use a ref in this way, React will preserve it for you, and there will be no need to use _hmrPreserveKeys.

_hmrPreserveKeys is only relevant in development and has not effect in production environment. Accordingly, you should only update this array when environment is development, so that it can be tree-shaken during production builds.

in addition to state, props, and hooks.

MyComponentMethods extends ComponentMethods {
// Some class member definitions...

constructor() {
if (process.env.NODE_ENV === 'development') {
this._hmrPreserveKeys.push('inputId', 'unsubscribeCallback');
}
}

// Method definitions...
}
With the above example, whenever HMR occurs, `this.inputId` and `this.unsubscribeCallback`
will maintain there existing values, while everything else will be recreated. Meanwhile,
because the code is written in an environment condition, it should be easy to strip it from the
production build to avoid shipping dead code
_onHmrUpdate?: <TInstance extends BaseClasses.ComponentInstance<TProps>>(
    oldInstance: TInstance,
) => void

Handle complex update logic whenever your component instance is updated through HMR. The function is called on the new instance, and it receives the old instance as the only argument. So you can access data from the old instance, and reinitialize any processes on the new instance as needed.

_onHmrUpdate is only relevant in development and has not effect in production environment. Accordingly, you should only assign this function when environment is development, so that it can be tree-shaken during production builds.

MyComponentMethods extends ComponentMethods {
// Some class member definitions...

constructor() {
if (process.env.NODE_ENV === 'development') {
this._onHmrUpdate = () => {
// Your custom hmr logic here.
};
}
}

// Method definitions...

Accessors

  • get templateContext(): ReturnType<this["beforeRender"]>
  • Holds the object returned by beforeRender.

    This is useful when you need to render some state or props in a transformed format. Put the transformation logic in beforeRender to the keep the function component template clean.


    Returns ReturnType<this["beforeRender"]>

    class MyComponentLogic extends ComponentInstance {
    beforeRender = () => {
    const title = `My Site | ${this.props.title}`;
    return { title };
    }
    }
    const MyComponent = (props) => {
    const self = useInstance(MyComponentLogic, props);
    const { template: ctx, state } = self;

    return (
    <h1>
    {ctx.title}
    </h1>
    <p>{props.description}</p>
    );
    }

Methods

  • Called before each instance of your component is mounted. It receives the initial props object and should return an object with the initial values for your component's state.

    Parameters

    Returns object

  • Call React hooks from here. If your component needs access to values return from the hooks you call, expose those values by returning an object with said values.

    The returned object will be accessible as this.hooks within your component class.

    Returns void | object