Skip to content

Commit cd05df3

Browse files
authored
Merge pull request #3020 from element-hq/robin/clarify-use-latest
Clarify what useLatest is for
2 parents 91671d9 + 9b59544 commit cd05df3

File tree

2 files changed

+16
-21
lines changed

2 files changed

+16
-21
lines changed

src/room/GroupCallView.tsx

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
55
Please see LICENSE in the repository root for full details.
66
*/
77

8-
import {
9-
type FC,
10-
useCallback,
11-
useEffect,
12-
useMemo,
13-
useRef,
14-
useState,
15-
} from "react";
8+
import { type FC, useCallback, useEffect, useMemo, useState } from "react";
169
import { type MatrixClient } from "matrix-js-sdk/src/client";
1710
import {
1811
Room,
@@ -40,10 +33,7 @@ import { useProfile } from "../profile/useProfile";
4033
import { findDeviceByName } from "../utils/media";
4134
import { ActiveCall } from "./InCallView";
4235
import { MUTE_PARTICIPANT_COUNT, type MuteStates } from "./MuteStates";
43-
import {
44-
useMediaDevices,
45-
type MediaDevices,
46-
} from "../livekit/MediaDevicesContext";
36+
import { useMediaDevices } from "../livekit/MediaDevicesContext";
4737
import { useMatrixRTCSessionMemberships } from "../useMatrixRTCSessionMemberships";
4838
import { enterRTCSession, leaveRTCSession } from "../rtcSessionHelpers";
4939
import { useRoomEncryptionSystem } from "../e2ee/sharedKeyManagement";
@@ -154,12 +144,8 @@ export const GroupCallView: FC<Props> = ({
154144
);
155145

156146
const deviceContext = useMediaDevices();
157-
const latestDevices = useRef<MediaDevices | undefined>(undefined);
158-
latestDevices.current = deviceContext;
159-
160-
// TODO: why do we use a ref here instead of using muteStates directly?
161-
const latestMuteStates = useRef<MuteStates | undefined>(undefined);
162-
latestMuteStates.current = muteStates;
147+
const latestDevices = useLatest(deviceContext);
148+
const latestMuteStates = useLatest(muteStates);
163149

164150
useEffect(() => {
165151
const defaultDeviceSetup = async ({
@@ -232,7 +218,15 @@ export const GroupCallView: FC<Props> = ({
232218
void enterRTCSession(rtcSession, perParticipantE2EE);
233219
}
234220
}
235-
}, [widget, rtcSession, preload, skipLobby, perParticipantE2EE]);
221+
}, [
222+
widget,
223+
rtcSession,
224+
preload,
225+
skipLobby,
226+
perParticipantE2EE,
227+
latestDevices,
228+
latestMuteStates,
229+
]);
236230

237231
const [left, setLeft] = useState(false);
238232
const [leaveError, setLeaveError] = useState<Error | undefined>(undefined);

src/useLatest.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ Please see LICENSE in the repository root for full details.
88
import { type RefObject, useRef } from "react";
99

1010
export interface LatestRef<T> extends RefObject<T> {
11-
current: T;
11+
current: T; // Always defined, unlike RefObject["current"]
1212
}
1313

1414
/**
1515
* React hook that returns a ref containing the value given on the latest
16-
* render.
16+
* render. Useful for accessing the latest value of something in an effect or
17+
* callback when you don't want reactivity.
1718
*/
1819
export function useLatest<T>(value: T): LatestRef<T> {
1920
const ref = useRef<T>(value);

0 commit comments

Comments
 (0)