Skip to content

Commit

Permalink
Type fixes for react v19 compatibility
Browse files Browse the repository at this point in the history
Two things:

- import `JSX` rather than expecting it to be a global namespace
- require a default value for `useRef`

I found these whilst working on #2874
  • Loading branch information
hughns committed Jan 8, 2025
1 parent d985bd3 commit 7dab56e
Show file tree
Hide file tree
Showing 17 changed files with 32 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
*/

import { type FC, Suspense, useEffect, useState } from "react";
import { type FC, type JSX, Suspense, useEffect, useState } from "react";
import { BrowserRouter, Route, useLocation, Routes } from "react-router-dom";
import * as Sentry from "@sentry/react";
import { TooltipProvider } from "@vector-im/compound-web";
Expand Down
1 change: 1 addition & 0 deletions src/ClientContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
useContext,
useRef,
useMemo,
type JSX,
} from "react";
import { useNavigate } from "react-router-dom";
import { logger } from "matrix-js-sdk/src/logger";
Expand Down
2 changes: 1 addition & 1 deletion src/auth/useInteractiveRegistration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const useInteractiveRegistration = (
undefined,
);

const authClient = useRef<MatrixClient>();
const authClient = useRef<MatrixClient | undefined>(undefined);
if (!authClient.current) {
authClient.current = createClient({
baseUrl: Config.defaultHomeserverUrl()!,
Expand Down
2 changes: 1 addition & 1 deletion src/auth/useRecaptcha.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export function useRecaptcha(sitekey?: string): {
} {
const { t } = useTranslation();
const [recaptchaId] = useState(() => randomString(16));
const promiseRef = useRef<RecaptchaPromiseRef>();
const promiseRef = useRef<RecaptchaPromiseRef | undefined>(undefined);

useEffect(() => {
if (!sitekey) return;
Expand Down
8 changes: 7 additions & 1 deletion src/grid/TileWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@ SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
*/

import { type ComponentType, memo, type RefObject, useRef } from "react";
import {
type ComponentType,
type JSX,
memo,
type RefObject,
useRef,
} from "react";
import { type EventTypes, type Handler, useDrag } from "@use-gesture/react";
import { type SpringValue } from "@react-spring/web";
import classNames from "classnames";
Expand Down
1 change: 1 addition & 0 deletions src/input/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
forwardRef,
type ReactNode,
useId,
type JSX,
} from "react";
import classNames from "classnames";

Expand Down
2 changes: 1 addition & 1 deletion src/input/StarRatingInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Copyright 2023, 2024 New Vector Ltd.
SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
*/
import { useState } from "react";
import { useState, type JSX } from "react";
import { useTranslation } from "react-i18next";

import styles from "./StarRatingInput.module.css";
Expand Down
1 change: 1 addition & 0 deletions src/livekit/MediaDevicesContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
useMemo,
useRef,
useState,
type JSX,
} from "react";
import { createMediaDeviceObserver } from "@livekit/components-core";
import { map, startWith } from "rxjs";
Expand Down
1 change: 1 addition & 0 deletions src/reactions/useReactionsSender.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
type ReactNode,
useCallback,
useMemo,
type JSX,
} from "react";
import { type MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession";
import { logger } from "matrix-js-sdk/src/logger";
Expand Down
4 changes: 2 additions & 2 deletions src/room/GroupCallView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,11 @@ export const GroupCallView: FC<Props> = ({
);

const deviceContext = useMediaDevices();
const latestDevices = useRef<MediaDevices>();
const latestDevices = useRef<MediaDevices | undefined>(undefined);
latestDevices.current = deviceContext;

// TODO: why do we use a ref here instead of using muteStates directly?
const latestMuteStates = useRef<MuteStates>();
const latestMuteStates = useRef<MuteStates | undefined>(undefined);
latestMuteStates.current = muteStates;

useEffect(() => {
Expand Down
1 change: 1 addition & 0 deletions src/room/InCallView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
useMemo,
useRef,
useState,
type JSX,
} from "react";
import useMeasure from "react-use-measure";
import { type MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession";
Expand Down
2 changes: 1 addition & 1 deletion src/room/LobbyView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
*/

import { type FC, useCallback, useMemo, useState } from "react";
import { type FC, useCallback, useMemo, useState, type JSX } from "react";
import { useTranslation } from "react-i18next";
import { type MatrixClient } from "matrix-js-sdk/src/matrix";
import { Button } from "@vector-im/compound-web";
Expand Down
9 changes: 8 additions & 1 deletion src/room/RoomPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@ SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
*/

import { type FC, useEffect, useState, type ReactNode, useRef } from "react";
import {
type FC,
useEffect,
useState,
type ReactNode,
useRef,
type JSX,
} from "react";
import { logger } from "matrix-js-sdk/src/logger";
import { useTranslation } from "react-i18next";
import { CheckIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
Expand Down
2 changes: 1 addition & 1 deletion src/room/useLoadGroupCall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export const useLoadGroupCall = (
viaServers: string[],
): GroupCallStatus => {
const [state, setState] = useState<GroupCallStatus>({ kind: "loading" });
const activeRoom = useRef<Room>();
const activeRoom = useRef<Room | undefined>(undefined);
const { t } = useTranslation();

const bannedError = useCallback(
Expand Down
2 changes: 1 addition & 1 deletion src/settings/RageshakeButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Please see LICENSE in the repository root for full details.
*/

import { useTranslation } from "react-i18next";
import { type FC, useCallback } from "react";
import { type FC, useCallback, type JSX } from "react";
import { Button } from "@vector-im/compound-web";
import { logger } from "matrix-js-sdk/src/logger";

Expand Down
3 changes: 1 addition & 2 deletions src/useInitial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { useRef } from "react";
* React hook that returns the value given on the initial render.
*/
export function useInitial<T>(getValue: () => T): T {
const ref = useRef<{ value: T }>();
ref.current ??= { value: getValue() };
const ref = useRef<{ value: T }>({ value: getValue() });
return ref.current.value;
}
4 changes: 2 additions & 2 deletions src/useReactiveState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ export const useReactiveState = <T>(
updateFn: (prevState?: T) => T,
deps: DependencyList,
): [T, Dispatch<SetStateAction<T>>] => {
const state = useRef<T>();
const state = useRef<T | undefined>(undefined);
if (state.current === undefined) state.current = updateFn();
const prevDeps = useRef<DependencyList>();
const prevDeps = useRef<DependencyList | undefined>(undefined);

// Since we store the state in a ref, we use this counter to force an update
// when someone calls setState
Expand Down

0 comments on commit 7dab56e

Please sign in to comment.