feat(31-01): refactor useMixerHelper to use composed selectors

- Replace 21 individual useSelector calls with 6 composed selectors
- Import shallowEqual from react-redux for object comparison
- Import composed selectors (selectCoreMixerState, selectTrackMixerState, etc.)
- Remove 16 individual selector imports no longer needed
- Destructure composed results for backward compatibility
- Total useSelector calls reduced from 28 to 13

Performance: Single mixer field change now triggers 6 selector runs
instead of 21, with shallowEqual preventing unnecessary re-renders
when composed object contents haven't changed.
This commit is contained in:
Nuwan 2026-03-05 19:10:24 +05:30
parent 0630ebdd3f
commit 43b99c549d
1 changed files with 26 additions and 44 deletions

View File

@ -1,28 +1,15 @@
import { useEffect, useMemo, useCallback, useRef } from 'react'; import { useEffect, useMemo, useCallback, useRef } from 'react';
import { useSelector, useDispatch } from 'react-redux'; import { useSelector, useDispatch, shallowEqual } from 'react-redux';
import { selectActiveSession, selectInSession } from '../store/features/activeSessionSlice'; import { selectActiveSession, selectInSession } from '../store/features/activeSessionSlice';
import { import {
selectChatMixer, // Composed selectors (use these instead of individual ones)
selectBroadcastMixer, selectCoreMixerState,
selectRecordingMixer, selectTrackMixerState,
selectRecordingTrackMixers, selectMixerLookupTables,
selectBackingTrackMixers, selectMasterPersonalMixers,
selectJamTrackMixers, selectMixerMetadata,
selectMetronomeTrackMixers, selectSimulatedCategoryMixers,
selectAdhocTrackMixers, // Actions (still needed)
selectMasterMixers,
selectPersonalMixers,
selectAllMixers,
selectMixersByResourceId,
selectMixersByTrackId,
selectMetronome,
selectMetronomeSettings,
selectMediaSummary,
selectNoAudioUsers,
selectClientsWithAudioOverride,
selectSimulatedMusicCategoryMixers,
selectSimulatedChatCategoryMixers,
selectMixersReady,
setMasterMixers, setMasterMixers,
setPersonalMixers, setPersonalMixers,
organizeMixers, organizeMixers,
@ -68,28 +55,23 @@ const useMixerHelper = () => {
const previousMyTracksRef = useRef([]); const previousMyTracksRef = useRef([]);
const previousMixerIdsRef = useRef(null); const previousMixerIdsRef = useRef(null);
// Redux selectors - replace all useState calls // Composed selectors with shallowEqual - reduces 21 subscriptions to 6
const chatMixer = useSelector(selectChatMixer); const coreMixers = useSelector(selectCoreMixerState, shallowEqual);
const broadcastMixer = useSelector(selectBroadcastMixer); const trackMixers = useSelector(selectTrackMixerState, shallowEqual);
const recordingMixer = useSelector(selectRecordingMixer); const lookupTables = useSelector(selectMixerLookupTables, shallowEqual);
const recordingTrackMixers = useSelector(selectRecordingTrackMixers); const masterPersonal = useSelector(selectMasterPersonalMixers, shallowEqual);
const backingTrackMixers = useSelector(selectBackingTrackMixers); const metadata = useSelector(selectMixerMetadata, shallowEqual);
const jamTrackMixers = useSelector(selectJamTrackMixers); const simulatedMixers = useSelector(selectSimulatedCategoryMixers, shallowEqual);
const metronomeTrackMixers = useSelector(selectMetronomeTrackMixers);
const adhocTrackMixers = useSelector(selectAdhocTrackMixers); // Destructure for backward compatibility with rest of hook
const masterMixers = useSelector(selectMasterMixers); const { chatMixer, broadcastMixer, recordingMixer } = coreMixers;
const personalMixers = useSelector(selectPersonalMixers); const { recordingTrackMixers, backingTrackMixers, jamTrackMixers,
const allMixers = useSelector(selectAllMixers); metronomeTrackMixers, adhocTrackMixers } = trackMixers;
const mixersByResourceId = useSelector(selectMixersByResourceId); const { allMixers, mixersByResourceId, mixersByTrackId } = lookupTables;
const mixersByTrackId = useSelector(selectMixersByTrackId); const { masterMixers, personalMixers } = masterPersonal;
const metronome = useSelector(selectMetronome); const { metronome, metronomeSettings, mediaSummary, noAudioUsers,
const metronomeSettings = useSelector(selectMetronomeSettings); clientsWithAudioOverride, isReady: isReadyRedux } = metadata;
const mediaSummary = useSelector(selectMediaSummary); const { simulatedMusicCategoryMixers, simulatedChatCategoryMixers } = simulatedMixers;
const noAudioUsers = useSelector(selectNoAudioUsers);
const clientsWithAudioOverride = useSelector(selectClientsWithAudioOverride);
const simulatedMusicCategoryMixers = useSelector(selectSimulatedMusicCategoryMixers);
const simulatedChatCategoryMixers = useSelector(selectSimulatedChatCategoryMixers);
const isReadyRedux = useSelector(selectMixersReady);
// Media data from mediaSlice // Media data from mediaSlice
const backingTracks = useSelector(selectBackingTracks); const backingTracks = useSelector(selectBackingTracks);