Enable react-compiler eslint to spot antipatterns (#28652)

* Switch to React18 useId

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Enable react-compiler eslint

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Fix an easy one

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Disable in tests

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Fix usage of useRef as memoization

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Fix mutation of external values in hooks

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Make React compiler happy about some frankly non-issues

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Fix MapMock

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Revert MemberListViewModel.tsx changes and disable linter per line

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Make viewmodel compatible with react-compiler linter

- Remove searchQuery ref/state and instead pass this query to the
  loadMember function.
- Now we no longer need a separate search function

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
Co-authored-by: R Midhun Suresh <hi@midhun.dev>
This commit is contained in:
Michael Telatynski
2025-01-16 12:26:00 +00:00
committed by GitHub
parent e5ca7954c8
commit ef1597ff2d
35 changed files with 146 additions and 136 deletions

View File

@@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
*/
import { TypedEventEmitter } from "matrix-js-sdk/src/matrix";
import React, { ContextType, createContext, memo, ReactNode, useContext, useEffect, useRef, useState } from "react";
import React, { ContextType, createContext, memo, ReactNode, useContext, useEffect, useMemo, useState } from "react";
import { objectKeyChanges } from "../utils/objects.ts";
import { useTypedEventEmitter } from "../hooks/useEventEmitter.ts";
@@ -48,15 +48,16 @@ const ScopedRoomContext = createContext<EfficientContext<ContextValue> | undefin
// Uses react memo and leverages splatting the value to ensure that the context is only updated when the state changes (shallow compare)
export const ScopedRoomContextProvider = memo(
({ children, ...state }: { children: ReactNode } & ContextValue): JSX.Element => {
const contextRef = useRef(new EfficientContext<ContextValue>(state));
// eslint-disable-next-line react-compiler/react-compiler,react-hooks/exhaustive-deps
const context = useMemo(() => new EfficientContext<ContextValue>(state), []);
useEffect(() => {
contextRef.current.setState(state);
}, [state]);
context.setState(state);
}, [context, state]);
// Includes the legacy RoomContext provider for backwards compatibility with class components
return (
<RoomContext.Provider value={state}>
<ScopedRoomContext.Provider value={contextRef.current}>{children}</ScopedRoomContext.Provider>
<ScopedRoomContext.Provider value={context}>{children}</ScopedRoomContext.Provider>
</RoomContext.Provider>
);
},

View File

@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
Please see LICENSE files in the repository root for full details.
*/
import { ReactNode, createContext, useCallback, useContext, useEffect, useRef, useState } from "react";
import { ReactNode, createContext, useCallback, useContext, useEffect, useState, useMemo } from "react";
/**
* A ToastContext helps components display any kind of toast message and can be provided
@@ -33,19 +33,19 @@ export function useToastContext(): ToastRack {
* the ToastRack object that should be provided to the context
*/
export function useActiveToast(): [ReactNode | undefined, ToastRack] {
const toastRack = useRef(new ToastRack());
const toastRack = useMemo(() => new ToastRack(), []);
const [activeToast, setActiveToast] = useState<ReactNode | undefined>(toastRack.current.getActiveToast());
const [activeToast, setActiveToast] = useState<ReactNode | undefined>(toastRack.getActiveToast());
const updateCallback = useCallback(() => {
setActiveToast(toastRack.current.getActiveToast());
setActiveToast(toastRack.getActiveToast());
}, [setActiveToast, toastRack]);
useEffect(() => {
toastRack.current.setCallback(updateCallback);
toastRack.setCallback(updateCallback);
}, [toastRack, updateCallback]);
return [activeToast, toastRack.current];
return [activeToast, toastRack];
}
interface DisplayedToast {