first commit
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
# `hooks/use-midi-devices`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
`useMidiDevices()` returns the live `{ inputs, outputs }` device-list
|
||||
view, re-rendering whenever the provider's `stateVersion` advances —
|
||||
i.e. whenever a Web MIDI `statechange` event fires (device plugged
|
||||
in, unplugged, or its state otherwise changed). It is a thin wrapper
|
||||
over `useMidi()` for components that only need the device lists and
|
||||
want a narrower call site. Use this hook in device-picker UIs.
|
||||
|
||||
## Features
|
||||
|
||||
- `inputs` and `outputs` are `readonly WebMIDIInput[]` /
|
||||
`readonly WebMIDIOutput[]` materialised on every state change.
|
||||
- Stable array identity between state changes — safe to pass to
|
||||
`key` in renders without forcing unnecessary remounts.
|
||||
- No subscription bookkeeping — the underlying provider already owns
|
||||
the single `onstatechange` listener.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```tsx
|
||||
import { useMidiDevices } from "@suaveplan/react-midi";
|
||||
|
||||
function DeviceCount() {
|
||||
const { inputs, outputs } = useMidiDevices();
|
||||
return (
|
||||
<p>
|
||||
{inputs.length} inputs, {outputs.length} outputs
|
||||
</p>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```tsx
|
||||
function PortPicker({ value, onChange }: {
|
||||
value: string | null;
|
||||
onChange: (id: string | null) => void;
|
||||
}) {
|
||||
const { inputs } = useMidiDevices();
|
||||
return (
|
||||
<select
|
||||
value={value ?? ""}
|
||||
onChange={(e) => onChange(e.target.value || null)}
|
||||
>
|
||||
<option value="">(none)</option>
|
||||
{inputs.map((i) => (
|
||||
<option key={i.id} value={i.id}>
|
||||
{i.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `useMidiDevices(): { inputs, outputs }`
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
This hook deliberately avoids duplicating the `useMidi` snapshot —
|
||||
it simply destructures and re-projects. Callers that also need the
|
||||
`status` or `error` should reach for `useMidi` instead.
|
||||
|
||||
Because the underlying `useMidi` re-materialises its `inputs` and
|
||||
`outputs` arrays only when the provider's `stateVersion` advances,
|
||||
the values returned here are referentially stable between
|
||||
`statechange` events. That means downstream effects keyed on
|
||||
`inputs` or `outputs` do not fire on every render — only when the
|
||||
device list actually changes — which matters for a device-picker UI
|
||||
that triggers expensive operations (e.g. preset reloads) on the
|
||||
selected device.
|
||||
Reference in New Issue
Block a user