npm package: @matchlighter/meta_components
Description: Meta Component's primary function is to add snippets of functionality to Class-Based components. It's basically React Hooks for class components.
Author: Matchlighter
Latest version: 0.6.10

# @matchlighter/meta_components

Meta Component's primary function is to add snippets of functionality to Class-Based components.
It's basically React Hooks for class components.

I'm a child of the OOP Generation, so OOP tends to make more sense and looks cleaner to me.
However, I really liked the idea and functionality behind hooks like `useContext` and I wanted similar features in Class-Based components without committing any massive, eye-paining sins (like nested Context Consumers to pass multiple Contexts to one Component).

This library is designed to be very extensible, allowing other libraries to write their own meta components.

## Design
A "Meta Component" is a custom construct that is initialized when a `@with_meta_components`-decorated Class Component is constructed.
Most simply, meta-components are a set of React Hooks that are run next to, and then integrated with, a Class Component.
This is achieved by wrapping the Class Component in a special functional component.
The functional component
1. Instantiates the wrapped component
2. Analyzes it for which meta-components it uses
3. Creates the appropriate "Managers" for each meta-component
4. Triggers each manager's `process_hooks` method

### Managers
Managers are intended to be Singleton for each type of meta-component.

For example, there's a built-in `@hook` meta-component. When used, the `@hook` decorator registers that the calling Component needs the `HooksMetaManager` Manager when the Component is constructed. It then registers details about the hook that the developer wants to be invoked. When the Component is constructed, the special wrapper function instantiates a `HooksMetaManager` and tells it to `process_hooks`. It then reads the data stored by `@hook` and invokes the hooks.

You _could_ create a Manager Factory and register a separate Manager Class for each `@` usage as well, but the one manager class per Meta Component type is preferred.

## Built In Meta components
`meta-components` ships with some simple, built-int meta-components:

### `@hook`
This meta-component is used as a property-decorator, like so:
```typescript
@hook(() => useContext(SomeContext)) accessor value: SomeContextType;
```
The value returned by the hook is set as the value of the decorated property.

### `@context`
Because the above pattern would be so common, a shortcut is provided that can be used like such:
```typescript
@context(SomeContext) accessor value: SomeContextType;
```

### `@mount_effect`
This hook can decorate a class method. It will call the decorated method when the component is mounted.

### `@hook_callback`
This meta-component is similar to `@hook`, but instead of having it's return value set as the value of a class-property, the decorated value/method is passed to the hook. `@mount_effect` uses this internally. As an example, here is how you could implement `@mount_effect`:
```typescript
@hook_callback((f) => useEffect(f, []))
onEffect() {
    // Do Something on Mount
}
```

### `@autorun`
If you're using MobX for state management, there's also an `@autorun` meta-component. This meta-component will setup a MobX Autorun (from the decorated method) when the Component mounts and ensure that it is disposed when the Component unmounts. It may be used like so:
```typescript
@autorun({ /* MobX Autorun options*/ })
autorunningMethod() {
    // Read and do something with an Observable
}
```

## Extending
For an example of an external library leveraging meta-components, see `@matchlighter/fetcher`.