72 lines
2.1 KiB
Markdown
72 lines
2.1 KiB
Markdown
# React Hooks Error Fix - TripPlanner
|
|
|
|
## Problem
|
|
```
|
|
Uncaught Error: Rendered more hooks than during the previous render.
|
|
```
|
|
|
|
## Root Cause
|
|
The `useMemo` hooks for `activeDayPlaces` and `activeDayMapPlaces` were placed AFTER the early return statements (`if (loading)` and `if (!trip)`). This violated React's Rules of Hooks, which require all hooks to be called in the same order on every render.
|
|
|
|
### Before (Incorrect):
|
|
```typescript
|
|
}, [trip?.days]);
|
|
|
|
if (loading) {
|
|
return <LoadingSkeleton />;
|
|
}
|
|
|
|
if (!trip) {
|
|
return <NotFoundMessage />;
|
|
}
|
|
|
|
// ❌ These hooks are called conditionally!
|
|
const activeDayPlaces = React.useMemo(() => { ... }, [activeDayId, trip?.days]);
|
|
const activeDayMapPlaces = React.useMemo(() => { ... }, [allPlaces, activeDayId]);
|
|
```
|
|
|
|
When `loading` is true or `trip` is null, the component returns early and these hooks never get called, causing React to detect a different number of hooks between renders.
|
|
|
|
## Solution
|
|
Moved both `useMemo` hooks BEFORE the early return statements.
|
|
|
|
### After (Correct):
|
|
```typescript
|
|
}, [trip?.days]);
|
|
|
|
// ✅ Hooks are always called in the same order
|
|
const activeDayPlaces = React.useMemo(() => {
|
|
if (!activeDayId || !trip?.days) return [];
|
|
const activeDay = trip.days.find((d: any) => d.id === activeDayId);
|
|
return activeDay?.places || [];
|
|
}, [activeDayId, trip?.days]);
|
|
|
|
const activeDayMapPlaces = React.useMemo(() => {
|
|
return allPlaces.filter(p => p.dayId === activeDayId);
|
|
}, [allPlaces, activeDayId]);
|
|
|
|
if (loading) {
|
|
return <LoadingSkeleton />;
|
|
}
|
|
|
|
if (!trip) {
|
|
return <NotFoundMessage />;
|
|
}
|
|
```
|
|
|
|
## React Rules of Hooks
|
|
1. **Only call hooks at the top level** - Don't call hooks inside loops, conditions, or nested functions
|
|
2. **Only call hooks from React functions** - Call them from React function components or custom hooks
|
|
3. **Hooks must be called in the same order** - Every render must call the same hooks in the same sequence
|
|
|
|
## Files Changed
|
|
- `src/pages/TripPlanner.tsx` (lines 873-883)
|
|
|
|
## Verification
|
|
- ✅ Lint: Passed
|
|
- ✅ TypeScript: No errors
|
|
- ✅ Hooks order: Correct (all hooks before early returns)
|
|
|
|
## Status
|
|
**FIXED** ✅
|