# `hooks/use-midi-devices` _(no submodules)_ ## 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 (

{inputs.length} inputs, {outputs.length} outputs

); } ``` ## Usage: Advanced ```tsx function PortPicker({ value, onChange }: { value: string | null; onChange: (id: string | null) => void; }) { const { inputs } = useMidiDevices(); return ( ); } ``` ## 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.