Description
Currently, TrackDetailScreen resolves track via getTrackById and passes it directly to hook consumers (useOfflineGeofence, useTrackDownload, useFeedbackTrigger). Since React Hooks must be executed unconditionally, all these hooks are typed to accept undefined or null, requiring nullish coalescing checks (e.g., track?.startCoordinates ?? { latitude: 0, longitude: 0 }).
We should refactor this screen using a Container-Presenter pattern:
- The container screen (
TrackDetailScreen) handles loading, error states, and checks if track is defined. If track is undefined, it renders the NotFound view immediately.
- If the
track exists, it renders a child presenter component (e.g., TrackDetailContent) passing the guaranteed LocalTrackMetadata as a prop.
- The child presenter component calls all track-specific hooks unconditionally without needing
undefined null checks.
Benefits
- Strict Type Safety: Hooks do not need to accept
undefined or null track parameter.
- Cleaner Code: Removes verbose fallback values in hook invocations.
- Separation of Concerns: Container handles screen routing and resolution; presenter handles UI layout and media playback logic.
Description
Currently,
TrackDetailScreenresolvestrackviagetTrackByIdand passes it directly to hook consumers (useOfflineGeofence,useTrackDownload,useFeedbackTrigger). Since React Hooks must be executed unconditionally, all these hooks are typed to acceptundefinedornull, requiring nullish coalescing checks (e.g.,track?.startCoordinates ?? { latitude: 0, longitude: 0 }).We should refactor this screen using a Container-Presenter pattern:
TrackDetailScreen) handles loading, error states, and checks iftrackis defined. Iftrackis undefined, it renders theNotFoundview immediately.trackexists, it renders a child presenter component (e.g.,TrackDetailContent) passing the guaranteedLocalTrackMetadataas a prop.undefinednull checks.Benefits
undefinedornulltrack parameter.