refactor: Simplify state management and remove unnecessary memoization in playlist components

This commit is contained in:
skalthoff
2025-12-03 18:49:08 -08:00
parent 27b256a8c5
commit 2bccfc5d1a
3 changed files with 24 additions and 51 deletions

View File

@@ -1,5 +1,5 @@
import { BaseItemDto } from '@jellyfin/sdk/lib/generated-client/models'
import { memo, useMemo, useState } from 'react'
import { useState } from 'react'
import Toast from 'react-native-toast-message'
import {
YStack,
@@ -44,11 +44,8 @@ export default function AddToPlaylist({
isSuccess: playlistsFetchSuccess,
} = useUserPlaylists()
// Memoize the tracks array to prevent unnecessary re-renders
const tracksToAdd = useMemo(() => (tracks ? tracks : track ? [track] : []), [tracks, track])
// Memoize the display item to prevent recalculation
const displayItem = useMemo(() => source ?? track, [source, track])
const tracksToAdd = tracks ? tracks : track ? [track] : []
const displayItem = source ?? track
return (
<ScrollView>
@@ -103,14 +100,11 @@ interface AddToPlaylistRowProps {
}
/**
* Memoized row component to prevent unnecessary re-renders.
* Row component for adding tracks to a playlist.
* Uses ChildCount from playlist metadata instead of fetching all tracks,
* significantly reducing API calls.
*/
const AddToPlaylistRow = memo(function AddToPlaylistRow({
playlist,
tracks,
}: AddToPlaylistRowProps): React.JSX.Element {
function AddToPlaylistRow({ playlist, tracks }: AddToPlaylistRowProps): React.JSX.Element {
// Track local state for UI updates after success
const [isAdded, setIsAdded] = useState(false)
// Use ChildCount from playlist metadata - no need to fetch all tracks
@@ -167,4 +161,4 @@ const AddToPlaylistRow = memo(function AddToPlaylistRow({
</ListItem>
</YGroup.Item>
)
})
}

View File

@@ -8,7 +8,7 @@ import { StackActions, useNavigation } from '@react-navigation/native'
import { RootStackParamList } from '../../screens/types'
import { NativeStackNavigationProp } from '@react-navigation/native-stack'
import Sortable from 'react-native-sortables'
import { useCallback, useLayoutEffect } from 'react'
import { useLayoutEffect } from 'react'
import { useReducedHapticsSetting } from '../../stores/settings/app'
import { RenderItemInfo } from 'react-native-sortables/dist/typescript/types'
import { BaseItemDto } from '@jellyfin/sdk/lib/generated-client'

View File

@@ -1,14 +1,6 @@
import { BaseItemDto } from '@jellyfin/sdk/lib/generated-client/models'
import { UseMutateFunction, useMutation, useQueryClient } from '@tanstack/react-query'
import {
createContext,
ReactNode,
useCallback,
useContext,
useEffect,
useMemo,
useState,
} from 'react'
import { createContext, ReactNode, useContext, useEffect, useState } from 'react'
import { updatePlaylist } from '../../api/mutations/playlists'
import useHapticFeedback from '../../hooks/use-haptic-feedback'
import { useApi } from '../../stores'
@@ -94,7 +86,7 @@ const PlaylistContextInitializer = (playlist: BaseItemDto) => {
},
})
const handleCancel = useCallback(() => {
const handleCancel = () => {
setEditing(false)
setNewName(playlist.Name ?? '')
if (tracks) {
@@ -105,7 +97,7 @@ const PlaylistContextInitializer = (playlist: BaseItemDto) => {
})),
)
}
}, [playlist.Name, tracks])
}
// Sync tracks from query to local state when data loads
// Use stable IDs based on track.Id + index to avoid regenerating on every sync
@@ -127,33 +119,20 @@ const PlaylistContextInitializer = (playlist: BaseItemDto) => {
}
}, [editing, refetch])
return useMemo(
() => ({
playlist,
playlistTracks,
refetch,
isPending,
editing,
setEditing,
newName,
setNewName,
setPlaylistTracks,
useUpdatePlaylist,
handleCancel,
isUpdating,
}),
[
playlist,
playlistTracks,
refetch,
isPending,
editing,
newName,
useUpdatePlaylist,
handleCancel,
isUpdating,
],
)
return {
playlist,
playlistTracks,
refetch,
isPending,
editing,
setEditing,
newName,
setNewName,
setPlaylistTracks,
useUpdatePlaylist,
handleCancel,
isUpdating,
}
}
const PlaylistContext = createContext<PlaylistContext>({