> ## Documentation Index
> Fetch the complete documentation index at: https://docs.daily.co/llms.txt
> Use this file to discover all available pages before exploring further.

# useDevices

> Returns information about a participant's media devices and their states, along with helper functions that wrap daily-js device-related methods.

`useDevices(): Object`

For more information about the different error states, see the [`camera-error`](/reference/daily-js/events/settings-events#camera-error) event.

## Return value

Returns an object with the following properties:

<ResponseField name="cameraError" type="Object | null">
  Stores the most recent error object that was emitted through the [`camera-error`](/reference/daily-js/events/settings-events#camera-error) event.
</ResponseField>

<ResponseField name="cameras" type="Object[]">
  An array of [device objects](#device-object-properties) that contains information about each camera.
</ResponseField>

<ResponseField name="camState" type="string">
  <code>'idle' | 'pending' | 'not-supported' | 'granted' | 'blocked' | 'in-use' | 'not-found' | 'constraints-invalid' | 'constraints-none-specified' | 'undefined-mediadevices' | 'unknown'</code>, indicates the general state of camera access.
</ResponseField>

<ResponseField name="currentCam" type="Object | undefined">
  References the selected device in the `cameras` array.
</ResponseField>

<ResponseField name="currentMic" type="Object | undefined">
  References the selected device in the `microphones` array.
</ResponseField>

<ResponseField name="currentSpeaker" type="Object | undefined">
  References the selected device in the `speakers` array.
</ResponseField>

<ResponseField name="hasCamError" type="boolean">
  `true` in case `camState` is one of <code>'blocked' | 'in-use' | 'not-found' | 'constraints-invalid' | 'constraints-none-specified' | 'undefined-mediadevices' | 'unknown'</code>.
</ResponseField>

<ResponseField name="hasMicError" type="boolean">
  `true` in case `micState` is one of <code>'blocked' | 'in-use' | 'not-found' | 'constraints-invalid' | 'constraints-none-specified' | 'undefined-mediadevices' | 'unknown'</code>.
</ResponseField>

<ResponseField name="microphones" type="Object[]">
  An array of [device objects](#device-object-properties) that contains information about each microphone.
</ResponseField>

<ResponseField name="micState" type="string">
  <code>'idle' | 'pending' | 'not-supported' | 'granted' | 'blocked' | 'in-use' | 'not-found' | 'constraints-invalid' | 'constraints-none-specified' | 'undefined-mediadevices' | 'unknown'</code>, indicates the general state of microphone access.
</ResponseField>

<ResponseField name="refreshDevices" type="Function">
  Refreshes the list of devices using [`enumerateDevices()`](/reference/daily-js/instance-methods/enumerate-devices).
</ResponseField>

<ResponseField name="setCamera" type="Function">
  Switches to the camera with the specified `deviceId`. Calls [`setInputDevicesAsync()`](/reference/daily-js/instance-methods/set-input-devices-async).
</ResponseField>

<ResponseField name="setMicrophone" type="Function">
  Switches to the mic with the specified `deviceId`. Calls [`setInputDevicesAsync()`](/reference/daily-js/instance-methods/set-input-devices-async).
</ResponseField>

<ResponseField name="setSpeaker" type="Function">
  Switches to the speaker with the specified `deviceId`. Calls [`setOutputDeviceAsync()`](/reference/daily-js/instance-methods/set-output-device-async).
</ResponseField>

<ResponseField name="speakers" type="Object[]">
  An array of [device objects](#device-object-properties) that contains information about each speaker.
</ResponseField>

### About `camState` and `micState`

With 0.7.0 `camState` and `micState` have a new default value of `"idle"` (in previous versions of Daily React, this value was `"pending"`).
Both states remain `"idle"` as long as no device access has been requested, which is the case for rooms configured with `start_audio_off: true` and `start_video_off: true`.
Once device access is requested, `camState` and `micState` switch to `"pending"`, as long as device access is pending.
Once the user grants device access they will switch to `"granted"`. In case the user blocked device access they switch to `"blocked"` accordingly.
In case of an [error](/reference/daily-js/events/settings-events#camera-error) the most representative error state will be applied.

### Device object properties

<ResponseField name="cameras / microphones / speakers item" type="Object">
  <Expandable title="properties">
    <ResponseField name="device" type="Object">
      The same device information returned from [`enumerateDevices()`](/reference/daily-js/instance-methods/enumerate-devices).
    </ResponseField>

    <ResponseField name="selected" type="boolean">
      `true` when this specific device is currently being used by [`getUserMedia()`](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia).
    </ResponseField>

    <ResponseField name="state" type="string">
      <code>'granted' | 'in-use'</code>. `'granted'` means the device is available, `'in-use'` means the device is used by another app.
    </ResponseField>
  </Expandable>
</ResponseField>

```json theme={null}
{
  "cameras": [
    {
      "device": <Object>,
      "selected": true,
      "state": "granted",
    },
  ],
  "camState": "granted",
  "currentCam": <Object>,
  "currentMic": <Object>,
  "currentSpeaker": <Object>,
  "hasCamError": false,
  "hasMicError": true,
  "microphones": [
    {
      "device": <Object>,
      "selected": false,
      "state": "in-use",
    },
  ],
  "micState": "in-use",
  "refreshDevices": <Function>,
  "setCamera": <Function>,
  "setMicrophone": <Function>,
  "setSpeaker": <Function>,
  "speakers": [
    {
      "device": <Object>,
      "selected": false,
      "state": "granted",
    },
  ],
}
```

## Example

```jsx theme={null}
import { useDevices } from '@daily-co/daily-react';

export const UseDevicesDemo = () => {
  const devices = useDevices();

  return (
    <ul>
      <li>Cam: {devices.hasCamError ? 'Error' : 'OK'}</li>
      <li>Mic: {devices.hasMicError ? 'Error' : 'OK'}</li>
    </ul>
  );
};
```

## See also

<CardGroup>
  <Card title="daily-js methods" icon="code" iconType="solid">
    * [enumerateDevices()](/reference/daily-js/instance-methods/enumerate-devices)
    * [setInputDevicesAsync()](/reference/daily-js/instance-methods/set-input-devices-async)
    * [setOutputDeviceAsync()](/reference/daily-js/instance-methods/set-output-device-async)
  </Card>

  <Card title="Events" icon="bolt" iconType="solid">
    * [camera-error](/reference/daily-js/events/settings-events#camera-error)
  </Card>
</CardGroup>
