fix(hooks): useSessionState reset honours the current default, not a frozen one
Also found uncommitted in the shared tree; unrelated to agent panels, so it lands on its own. `reset` closed over `initialValue` from the first render, and its `useCallback` dep list deliberately omitted it — with an eslint-disable to silence the warning that was correctly pointing at the bug. Any caller whose default is computed (derived from props, from a fetch, from another piece of state) got reset to whatever that default happened to be on mount, which after the first render is the wrong value. Reads through a ref instead, so reset always sees the current default. The eslint-disable goes away because there is nothing left to suppress — the dep list is honest now. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -76,6 +76,8 @@ export function useSessionState<T>(key: string, initialValue: T) {
|
||||
valueRef.current = value;
|
||||
const setGlobalRef = useRef(setGlobal);
|
||||
setGlobalRef.current = setGlobal;
|
||||
const initialValueRef = useRef(initialValue);
|
||||
initialValueRef.current = initialValue;
|
||||
|
||||
const setValue = useCallback(
|
||||
(arg: React.SetStateAction<T>) => {
|
||||
@@ -86,11 +88,11 @@ export function useSessionState<T>(key: string, initialValue: T) {
|
||||
[key],
|
||||
);
|
||||
|
||||
// Read through the ref, not the closure: resetting means "whatever the default is now", and a
|
||||
// `useCallback` over `initialValue` would freeze the default from the render that built the callback.
|
||||
const reset = useCallback(() => {
|
||||
clearSessionValue(key);
|
||||
setGlobalRef.current(initialValue);
|
||||
// `initialValue` is read at reset time on purpose: resetting means "whatever the default is now".
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
setGlobalRef.current(initialValueRef.current);
|
||||
}, [key]);
|
||||
|
||||
return [value, setValue, reset] as const;
|
||||
|
||||
Reference in New Issue
Block a user