Skip to content

Commit a176474

Browse files
committed
fix(date-picker): eliminate infinite re-render on re-open with existing selection
The useEffect that syncs picker state on open had initialStart and initialEnd — Date objects computed on every render — in its dependency array. Because Object.is returns false for any two distinct Date instances, the effect fired on every render when open=true, calling setRangeStart/setRangeEnd and triggering another render, producing an infinite loop that crashed the page. Fix: compute start and end as local variables inside the effect and use the stable string props (props.startDate, props.endDate) as deps instead. Also removes the redundant typeof fileSize === 'number' guard in the multipart quota check — fileSize is z.number() (required) in the contract so it can never be undefined at that point.
1 parent 39bd68c commit a176474

2 files changed

Lines changed: 20 additions & 15 deletions

File tree

apps/sim/app/api/files/multipart/route.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,9 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
134134

135135
const config = getStorageConfig(storageContext)
136136

137-
if (
138-
!QUOTA_EXEMPT_STORAGE_CONTEXTS.has(context as StorageContext) &&
139-
typeof fileSize === 'number'
140-
) {
137+
if (!QUOTA_EXEMPT_STORAGE_CONTEXTS.has(context as StorageContext)) {
141138
const { checkStorageQuota } = await import('@/lib/billing/storage')
142-
const quotaCheck = await checkStorageQuota(userId, fileSize)
139+
const quotaCheck = await checkStorageQuota(userId, fileSize ?? 0)
143140
if (!quotaCheck.allowed) {
144141
return NextResponse.json(
145142
{ error: quotaCheck.error || 'Storage limit exceeded' },

apps/sim/components/emcn/components/date-picker/date-picker.tsx

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -553,25 +553,33 @@ const DatePicker = React.forwardRef<HTMLDivElement, DatePickerProps>((props, ref
553553

554554
React.useEffect(() => {
555555
if (open && isRangeMode) {
556-
setRangeStart(initialStart)
557-
setRangeEnd(initialEnd)
556+
const start = parseDate(props.startDate)
557+
const end = parseDate(props.endDate)
558+
setRangeStart(start)
559+
setRangeEnd(end)
558560
setSelectingEnd(false)
559561
if (showTime) {
560-
const sd = isRangeMode ? props.startDate : undefined
561-
const ed = isRangeMode ? props.endDate : undefined
562-
setStartTime(typeof sd === 'string' && sd.includes('T') ? sd.slice(11, 16) : '00:00')
563-
setEndTime(typeof ed === 'string' && ed.includes('T') ? ed.slice(11, 16) : '23:59')
562+
setStartTime(
563+
typeof props.startDate === 'string' && props.startDate.includes('T')
564+
? props.startDate.slice(11, 16)
565+
: '00:00'
566+
)
567+
setEndTime(
568+
typeof props.endDate === 'string' && props.endDate.includes('T')
569+
? props.endDate.slice(11, 16)
570+
: '23:59'
571+
)
564572
}
565-
if (initialStart) {
566-
setViewMonth(initialStart.getMonth())
567-
setViewYear(initialStart.getFullYear())
573+
if (start) {
574+
setViewMonth(start.getMonth())
575+
setViewYear(start.getFullYear())
568576
} else {
569577
const now = new Date()
570578
setViewMonth(now.getMonth())
571579
setViewYear(now.getFullYear())
572580
}
573581
}
574-
}, [open, isRangeMode, initialStart, initialEnd, showTime, props.startDate, props.endDate])
582+
}, [open, isRangeMode, props.startDate, props.endDate, showTime])
575583

576584
const singleValueKey = !isRangeMode && selectedDate ? selectedDate.getTime() : undefined
577585
const [prevSingleValueKey, setPrevSingleValueKey] = React.useState(singleValueKey)

0 commit comments

Comments
 (0)