# `hooks/use-audio-fx-plugin`
_(no submodules)_
## Purpose
`useAudioFxPlugin(pluginType)` instantiates a plugin via the
provider's `PluginRegistry.create(pluginType)` and memoises the
result. The hook is the canonical way to obtain a one-off plugin
instance (e.g. for a side-panel preview that is not in any chain).
Consumers who want to insert the plugin into a chain pass the
returned value to `usePluginChain(...).add(plugin)`.
The hook does not own or register factories. The provider can
auto-register factories via `options.plugins`; alternatively
`useAudioEngine().registry.register(...)` lets consumers add factories
dynamically.
## Features
- Instance memoised by `pluginType` for component lifetime.
- Throws `REACT_AUDIO.NO_PROVIDER` / `REACT_AUDIO.PROVIDER_PENDING`
outside / before-init.
- Throws `AudioFxError(AUDIO_FX.CHAIN_SLOT_NOT_FOUND)` if no factory
is registered for `pluginType`.
## Usage: Basic
```tsx
import { useAudioFxPlugin } from "@suaveplan/react-audio";
function PreviewEQ() {
const eq = useAudioFxPlugin("equaliser");
return ;
}
```
## Usage: Advanced
```tsx
import { useAudioEngine, useAudioFxPlugin, usePluginChain } from "@suaveplan/react-audio";
import { useEffect } from "react";
function EnsureRegistered() {
const { registry } = useAudioEngine();
useEffect(() => {
registry.register("delay", () => makeDelay());
}, [registry]);
return null;
}
function ChainAdder({ trackId }: { trackId: string }) {
const delay = useAudioFxPlugin("delay");
const { add } = usePluginChain(trackId);
return ;
}
```
## API Reference
- `useAudioFxPlugin(pluginType: string): AudioFxPlugin`.
## Implementation Notes
The hook memoises on `[registry, pluginType]` so a remount of the
provider (new registry identity) yields a fresh instance, but a
re-render with the same provider and `pluginType` returns the same
instance. The hook does not call `dispose()` on unmount because the
plugin is typically inserted into a chain whose lifecycle owns the
disposal. Consumers using the hook for a transient preview should
call `plugin.dispose()` in their own `useEffect` cleanup. Plugins
constructed by this hook are never auto-inserted into any chain —
the caller is responsible for placement (e.g. via
`usePluginChain(trackId).add(plugin)`). This separation lets the
same hook back per-track inserts, side-panel previews, and one-off
analyser taps.