From d382635597ac73824ae9f2a088ac38ef9a667495 Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Mon, 11 May 2026 16:31:51 +0000 Subject: [PATCH] Phase A: clear all react-hooks/exhaustive-deps warnings via useEffectEvent or hoisting Eliminate the four remaining missing-dependency warnings reported by react-hooks v7. Each one was a real stale-closure or re-trigger hazard; the fix matches the intent rather than just silencing the linter. - src/App.tsx (line 448): wrap showSessionExpired with useEffectEvent (onSessionExpired) so the prepare effect doesn't re-run on every showSessionExpired identity change but still calls the latest callback. Replace the two in-effect call sites. - src/components/furni-editor/views/FurniEditorSearchView.tsx: wrap the on-mount onSearch('', '', 1) call with useEffectEvent so the callback prop isn't a missing dependency. - src/components/notification-center/views/bubble-layouts/ NotificationBadgeReceivedBubbleView.tsx: wrap the "fetch badges only if empty on mount" check with useEffectEvent so badgeCodes.length isn't required as a dep (and won't re-fetch every count change). - src/components/navigator/views/room-settings/ NavigatorRoomSettingsRightsTabView.tsx: switch deps from roomData?.roomId to roomData (the body uses roomData.roomId after an early return; the linter wanted the whole object). - src/api/ui-settings/UiSettingsContext.tsx: hoist ALL_CSS_VARS outside the component (it's a static constant). After this, yarn eslint reports zero exhaustive-deps warnings across the whole src/. https://claude.ai/code/session_01GrR87LAqnAEyKG2ZbmQt5Q --- src/App.tsx | 8 +++++--- src/api/ui-settings/UiSettingsContext.tsx | 14 +++++++------- .../furni-editor/views/FurniEditorSearchView.tsx | 6 ++++-- .../NavigatorRoomSettingsRightsTabView.tsx | 2 +- .../NotificationBadgeReceivedBubbleView.tsx | 9 +++++++-- 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 1e7a35f..e54defc 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,5 @@ import { GetAssetManager, GetAvatarRenderManager, GetCommunication, GetConfiguration, GetLocalizationManager, GetRoomEngine, GetRoomSessionManager, GetSessionDataManager, GetSoundManager, GetStage, GetTexturePool, GetTicker, HabboWebTools, LegacyExternalInterface, LoadGameUrlEvent, NitroEventType, NitroLogger, NitroVersion, PrepareRenderer } from '@nitrots/nitro-renderer'; -import { FC, useCallback, useEffect, useRef, useState } from 'react'; +import { FC, useCallback, useEffect, useEffectEvent, useRef, useState } from 'react'; import { ClearRememberLogin, GetRememberLogin, GetUIVersion, StoreRememberLoginFromPayload } from './api'; import { Base } from './common'; import { LoadingView } from './components/loading/LoadingView'; @@ -316,6 +316,8 @@ export const App: FC<{}> = props => }; }, []); + const onSessionExpired = useEffectEvent(() => showSessionExpired()); + useEffect(() => { const prepare = async (width: number, height: number) => @@ -379,7 +381,7 @@ export const App: FC<{}> = props => return; } - showSessionExpired(); + onSessionExpired(); return; } } @@ -432,7 +434,7 @@ export const App: FC<{}> = props => { NitroLogger.error(err); setIsEnteringHotel(false); - showSessionExpired(); + onSessionExpired(); } }; diff --git a/src/api/ui-settings/UiSettingsContext.tsx b/src/api/ui-settings/UiSettingsContext.tsx index fb5abcb..0bde41d 100644 --- a/src/api/ui-settings/UiSettingsContext.tsx +++ b/src/api/ui-settings/UiSettingsContext.tsx @@ -60,6 +60,13 @@ const saveSettings = (settings: IUiSettings): void => {} }; +const ALL_CSS_VARS = [ + '--ui-accent-color', '--ui-accent-dark', + '--ui-ctx-bg', '--ui-ctx-header-bg', '--ui-ctx-item-bg1', '--ui-ctx-item-bg2', + '--ui-btn-primary-bg', '--ui-btn-primary-border', + '--ui-dark-bg', '--ui-dark-border' +]; + const sendComposer = (composer: any): void => { try @@ -189,13 +196,6 @@ export const UiSettingsProvider: FC = ({ children }) => const isCustomActive = settings.colorMode !== 'default'; - const ALL_CSS_VARS = [ - '--ui-accent-color', '--ui-accent-dark', - '--ui-ctx-bg', '--ui-ctx-header-bg', '--ui-ctx-item-bg1', '--ui-ctx-item-bg2', - '--ui-btn-primary-bg', '--ui-btn-primary-border', - '--ui-dark-bg', '--ui-dark-border' - ]; - useEffect(() => { const root = document.documentElement; diff --git a/src/components/furni-editor/views/FurniEditorSearchView.tsx b/src/components/furni-editor/views/FurniEditorSearchView.tsx index 4fb9af5..a1eccfb 100644 --- a/src/components/furni-editor/views/FurniEditorSearchView.tsx +++ b/src/components/furni-editor/views/FurniEditorSearchView.tsx @@ -1,4 +1,4 @@ -import { FC, useCallback, useEffect, useMemo, useState } from 'react'; +import { FC, useCallback, useEffect, useEffectEvent, useMemo, useState } from 'react'; import { Button, Column, Flex, LayoutFurniIconImageView, Text } from '../../../common'; import { FurniItem } from '../../../hooks/furni-editor'; @@ -30,9 +30,11 @@ export const FurniEditorSearchView: FC = props => const [ sortField, setSortField ] = useState('id'); const [ sortDir, setSortDir ] = useState('asc'); + const initialSearch = useEffectEvent(() => onSearch('', '', 1)); + useEffect(() => { - onSearch('', '', 1); + initialSearch(); }, []); const handleSearch = useCallback(() => diff --git a/src/components/navigator/views/room-settings/NavigatorRoomSettingsRightsTabView.tsx b/src/components/navigator/views/room-settings/NavigatorRoomSettingsRightsTabView.tsx index eede2d5..1c12f00 100644 --- a/src/components/navigator/views/room-settings/NavigatorRoomSettingsRightsTabView.tsx +++ b/src/components/navigator/views/room-settings/NavigatorRoomSettingsRightsTabView.tsx @@ -100,7 +100,7 @@ export const NavigatorRoomSettingsRightsTabView: FC diff --git a/src/components/notification-center/views/bubble-layouts/NotificationBadgeReceivedBubbleView.tsx b/src/components/notification-center/views/bubble-layouts/NotificationBadgeReceivedBubbleView.tsx index 8c1154e..edd866f 100644 --- a/src/components/notification-center/views/bubble-layouts/NotificationBadgeReceivedBubbleView.tsx +++ b/src/components/notification-center/views/bubble-layouts/NotificationBadgeReceivedBubbleView.tsx @@ -1,5 +1,5 @@ import { RequestBadgesComposer } from '@nitrots/nitro-renderer'; -import { FC, useEffect } from 'react'; +import { FC, useEffect, useEffectEvent } from 'react'; import { LocalizeText, NotificationBubbleItem, SendMessageComposer } from '../../../../api'; import { Flex, LayoutNotificationBubbleView, LayoutNotificationBubbleViewProps, Text } from '../../../../common'; import { useInventoryBadges } from '../../../../hooks'; @@ -14,9 +14,14 @@ export const NotificationBadgeReceivedBubbleView: FC + const requestBadgesIfEmpty = useEffectEvent(() => { if(badgeCodes.length === 0) SendMessageComposer(new RequestBadgesComposer()); + }); + + useEffect(() => + { + requestBadgesIfEmpty(); }, []); const handleWear = (event: React.MouseEvent) =>