Files
skills/docs/ui/react/react-midi/src/hooks/use-midi-devices/use-midi-devices.md
2026-05-29 08:20:56 +01:00

2.4 KiB

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

import { useMidiDevices } from "@suaveplan/react-midi";

function DeviceCount() {
    const { inputs, outputs } = useMidiDevices();
    return (
        <p>
            {inputs.length} inputs, {outputs.length} outputs
        </p>
    );
}

Usage: Advanced

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.