first commit
This commit is contained in:
72
docs/ui/react/react-midi/src/hooks/use-midi/use-midi.md
Normal file
72
docs/ui/react/react-midi/src/hooks/use-midi/use-midi.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# `hooks/use-midi`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
`useMidi()` is the most general hook in `@suaveplan/react-midi`. It
|
||||
returns the live `MidiContextValue` surface as
|
||||
`{ status, access, inputs, outputs, error }`, where `inputs` and
|
||||
`outputs` are arrays freshly materialised from the underlying
|
||||
`ReadonlyMap`s whenever the provider's `stateVersion` advances
|
||||
(i.e. whenever a port plugs or unplugs). Components that only need
|
||||
status or device-list snapshots can reach for this hook directly;
|
||||
specialised hooks (`useMidiInput`, `useMidiDevices`) wrap it for
|
||||
narrower use-cases.
|
||||
|
||||
The hook never throws on a `denied` / `unsupported` status — it
|
||||
*reports* the state. The only throw is the structural
|
||||
`REACT_MIDI.NO_PROVIDER` when rendered outside a provider.
|
||||
|
||||
## Features
|
||||
|
||||
- One snapshot of status, access, inputs, outputs, and last error.
|
||||
- Arrays re-materialise on `stateVersion` bumps; stable identity
|
||||
between bumps so consumers can pass them straight to `key`.
|
||||
- Returns empty arrays during `loading` / `denied` / `unsupported`.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```tsx
|
||||
import { useMidi } from "@suaveplan/react-midi";
|
||||
|
||||
function DeviceCounts() {
|
||||
const { status, inputs, outputs } = useMidi();
|
||||
if (status !== "granted") return <p>{status}</p>;
|
||||
return (
|
||||
<p>
|
||||
{inputs.length} ins / {outputs.length} outs
|
||||
</p>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```tsx
|
||||
function PermissionGate({ children }: { children: React.ReactNode }) {
|
||||
const { status, error } = useMidi();
|
||||
if (status === "loading") return <Spinner />;
|
||||
if (status === "unsupported")
|
||||
return <p>Web MIDI is not available in this browser.</p>;
|
||||
if (status === "denied")
|
||||
return <p>Permission denied: {error?.message}.</p>;
|
||||
return <>{children}</>;
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `useMidi(): UseMidiResult`
|
||||
- `interface UseMidiResult { status, access, inputs, outputs, error }`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The hook materialises `Array.from(access.inputs.values())` only when
|
||||
either `access` (root identity) or `stateVersion` (plug/unplug
|
||||
counter) changes — `useMemo` keys both into the dep list. This means
|
||||
consumers that pass `inputs.length` to a downstream effect avoid the
|
||||
"every render is a new array" trap that a naïve `[...map.values()]`
|
||||
would create.
|
||||
Reference in New Issue
Block a user