fix(ui): drop setState-in-effect in useAuthSessionExpiry
CI surfaced react-hooks/set-state-in-effect on the synchronous setState(computeState(token)) inside the useEffect body. The earlier shape mirrored token -> state via an effect, which is exactly the "you might not need an effect" pattern React 19's eslint rule now flags. Switch to derived state: compute during render, use a useReducer tick to force re-render on the 30s cadence (so relative timestamps stay current even when token props don't change). Same observable behavior, no cascading renders. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useReducer } from 'react'
|
||||||
import { useAuthStore } from '@/store/authStore'
|
import { useAuthStore } from '@/store/authStore'
|
||||||
|
|
||||||
const SOON_MS = 5 * 60 * 1000 // 5 minutes
|
const SOON_MS = 5 * 60 * 1000 // 5 minutes
|
||||||
@@ -53,14 +53,17 @@ function computeState(token: ReturnType<typeof useAuthStore.getState>['token']):
|
|||||||
*/
|
*/
|
||||||
export function useAuthSessionExpiry(): ExpiryState {
|
export function useAuthSessionExpiry(): ExpiryState {
|
||||||
const token = useAuthStore((s) => s.token)
|
const token = useAuthStore((s) => s.token)
|
||||||
const [state, setState] = useState<ExpiryState>(() => computeState(token))
|
// Derived state — computed during render, not synced via setState in an
|
||||||
|
// effect. The reducer here is only a tick counter that forces re-render on
|
||||||
|
// the 30s cadence so the relative timestamps stay current. See React 19
|
||||||
|
// guidance: https://react.dev/learn/you-might-not-need-an-effect
|
||||||
|
const [, tick] = useReducer((n: number) => n + 1, 0)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setState(computeState(token))
|
|
||||||
if (!token?.idle_expires_at || !token?.absolute_expires_at) return
|
if (!token?.idle_expires_at || !token?.absolute_expires_at) return
|
||||||
const interval = window.setInterval(() => setState(computeState(token)), 30_000)
|
const interval = window.setInterval(tick, 30_000)
|
||||||
return () => window.clearInterval(interval)
|
return () => window.clearInterval(interval)
|
||||||
}, [token])
|
}, [token])
|
||||||
|
|
||||||
return state
|
return computeState(token)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user