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