diff --git a/src/room/GroupCallView.tsx b/src/room/GroupCallView.tsx index 8bd7a622..163ddfd7 100644 --- a/src/room/GroupCallView.tsx +++ b/src/room/GroupCallView.tsx @@ -5,14 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE in the repository root for full details. */ -import { - type FC, - useCallback, - useEffect, - useMemo, - useRef, - useState, -} from "react"; +import { type FC, useCallback, useEffect, useMemo, useState } from "react"; import { type MatrixClient } from "matrix-js-sdk/src/client"; import { Room, @@ -40,10 +33,7 @@ import { useProfile } from "../profile/useProfile"; import { findDeviceByName } from "../utils/media"; import { ActiveCall } from "./InCallView"; import { MUTE_PARTICIPANT_COUNT, type MuteStates } from "./MuteStates"; -import { - useMediaDevices, - type MediaDevices, -} from "../livekit/MediaDevicesContext"; +import { useMediaDevices } from "../livekit/MediaDevicesContext"; import { useMatrixRTCSessionMemberships } from "../useMatrixRTCSessionMemberships"; import { enterRTCSession, leaveRTCSession } from "../rtcSessionHelpers"; import { useRoomEncryptionSystem } from "../e2ee/sharedKeyManagement"; @@ -154,12 +144,8 @@ export const GroupCallView: FC = ({ ); const deviceContext = useMediaDevices(); - const latestDevices = useRef(undefined); - latestDevices.current = deviceContext; - - // TODO: why do we use a ref here instead of using muteStates directly? - const latestMuteStates = useRef(undefined); - latestMuteStates.current = muteStates; + const latestDevices = useLatest(deviceContext); + const latestMuteStates = useLatest(muteStates); useEffect(() => { const defaultDeviceSetup = async ({ @@ -232,7 +218,15 @@ export const GroupCallView: FC = ({ void enterRTCSession(rtcSession, perParticipantE2EE); } } - }, [widget, rtcSession, preload, skipLobby, perParticipantE2EE]); + }, [ + widget, + rtcSession, + preload, + skipLobby, + perParticipantE2EE, + latestDevices, + latestMuteStates, + ]); const [left, setLeft] = useState(false); const [leaveError, setLeaveError] = useState(undefined); diff --git a/src/useLatest.ts b/src/useLatest.ts index 1a68aeb6..f5fdd937 100644 --- a/src/useLatest.ts +++ b/src/useLatest.ts @@ -8,12 +8,13 @@ Please see LICENSE in the repository root for full details. import { type RefObject, useRef } from "react"; export interface LatestRef extends RefObject { - current: T; + current: T; // Always defined, unlike RefObject["current"] } /** * React hook that returns a ref containing the value given on the latest - * render. + * render. Useful for accessing the latest value of something in an effect or + * callback when you don't want reactivity. */ export function useLatest(value: T): LatestRef { const ref = useRef(value);