Refactored the Daily Tasks page components to eliminate duplicate API calls and improve performance by implementing the "Lift State Up" pattern and ref-based duplicate call protection.
When switching between tabs (especially "Parse Log" and "Review & Submit"), multiple components were independently fetching the same data, resulting in:
- 4 duplicate calls on the Review & Submit tab (2 components × 2 React Strict Mode mounts)
- 2 duplicate calls on the Parse Log tab (1 component × 2 React Strict Mode mounts)
Review & Submit Tab (inline JSX)
├── SubmissionStatus (fetches status independently)
└── DashboardSummary (fetches status independently)
Result: 4 duplicate API calls to /api/monthly-reports/status
ReviewSubmitTab Component
├── Fetches status once with ref protection
├── SubmissionStatus (receives status as prop)
└── DashboardSummary (receives status as prop)
Result: 1 API call to /api/monthly-reports/status
-
Created
ReviewSubmitTabcomponent (/review-submit/ReviewSubmitTab.tsx)- Centralizes month status fetching
- Uses
useRefto prevent duplicate fetches - Tracks last filter value to avoid unnecessary re-fetches
- Provides
refreshStatuscallback for status updates
-
Refactored
SubmissionStatuscomponent- Removed internal
useEffectfor fetching status - Now accepts
status,loading, andonStatusChangeprops - Calls parent callback after successful submission
- Removed internal
-
Refactored
DashboardSummarycomponent- Removed internal
useEffectfor fetching month status - Now accepts optional
monthStatusprop - Determines approval state from prop
- Removed internal
-
Updated main page
- Replaced inline JSX with
ReviewSubmitTabcomponent - Removed unused imports
- Replaced inline JSX with
ParseTab Component
└── DailyPulseAIAssistant
└── Fetches active projects on mount (no protection)
Result: 2 duplicate calls to getActiveProjects()
ParseTab Component
└── DailyPulseAIAssistant
└── Fetches active projects with ref protection
Result: 1 call to getActiveProjects()
-
Updated
DailyPulseAIAssistantcomponent- Added
hasFetchedProjectsRefto track fetch state - Prevents duplicate fetches in React Strict Mode
- Resets ref on error to allow retry
- Maintains all existing functionality
- Added
-
Verified
ParseTabcomponent- Already has
isProcessingref for POST protection - No additional changes needed
- Already has
- ✅
useRefhooks track fetch state across re-renders - ✅ Early return if already fetched
- ✅ Works correctly in React Strict Mode (development)
- ✅ Smart error handling (resets on failure for retry)
- ✅ Single source of truth for shared data
- ✅ Props-based data flow (parent → children)
- ✅ Callback pattern for status updates
- ✅ Proper TypeScript typing
- ✅ Reduced API calls by 75% (4 → 1 on Review & Submit)
- ✅ Reduced API calls by 50% (2 → 1 on Parse Log)
- ✅ Lower server load
- ✅ Faster page transitions
src/app/(authenticated)/daily-tasks/
├── page.tsx # Main page (simplified)
├── DailyPulseTabs.tsx # Tab navigation
├── SubmissionStatus.tsx # Refactored (prop-based)
│
├── parse/
│ ├── ParseTab.tsx # Parse tab wrapper
│ ├── DailyPulseAIAssistant.tsx # Refactored (ref protection)
│ ├── TaskSummaryList.tsx # No changes needed
│ ├── TaskEditForm.tsx # No changes needed
│ └── index.ts
│
├── review-submit/
│ ├── ReviewSubmitTab.tsx # NEW: Centralized status fetching
│ └── index.ts # NEW: Export
│
└── dashboard/
├── DashboardSummary.tsx # Refactored (prop-based)
└── DashboardFilters.tsx # No changes needed
-
Performance
- Fewer API calls = faster page loads
- Reduced server load
- Better user experience
-
Maintainability
- Clear data flow (parent → children)
- Single source of truth
- Easier to debug and test
-
React Best Practices
- Proper state lifting
- Ref-based side effect protection
- Works correctly in Strict Mode
-
Type Safety
- Full TypeScript support
- Proper interface definitions
- No type errors
- Parse Log tab loads without duplicate calls
- Review & Submit tab loads without duplicate calls
- Switching between tabs doesn't cause extra fetches
- Month filter changes trigger single fetch
- Submission updates status correctly
- Edit/delete operations work as expected
- React Strict Mode doesn't cause duplicates
- Error handling works (retry on failure)
- No breaking changes to functionality
- All existing features preserved
- Component interfaces updated (backward compatible via optional props)
- No database or API changes required
- Review & Submit tab: 4 API calls on mount
- Parse Log tab: 2 API calls on mount
- Total: 6 API calls when switching tabs
- Review & Submit tab: 1 API call on mount
- Parse Log tab: 1 API call on mount
- Total: 2 API calls when switching tabs
Improvement: 67% reduction in API calls 🚀