|
1 | | -import { useCallback, useEffect, useState } from 'react' |
| 1 | +import { useCallback, useEffect, useLayoutEffect, useState } from 'react' |
2 | 2 |
|
3 | 3 | import type { Dispatch, SetStateAction } from 'react' |
4 | 4 |
|
@@ -26,6 +26,13 @@ type UseLocalStorageOptions<T> = { |
26 | 26 | * @default true |
27 | 27 | */ |
28 | 28 | initializeWithValue?: boolean |
| 29 | + /** |
| 30 | + * If 'max', useLayoutEffect will be used to ensure the most rapid update; ideal for |
| 31 | + * UI settings that affect initial render and the page layout. |
| 32 | + * If 'default', useEffect will be used to gracefully update without blocking the UI. |
| 33 | + * @default 'default' |
| 34 | + */ |
| 35 | + priority?: 'max' | 'default' |
29 | 36 | } |
30 | 37 |
|
31 | 38 | const IS_SERVER = typeof window === 'undefined' |
@@ -165,10 +172,13 @@ export function useLocalStorage<T>( |
165 | 172 | window.dispatchEvent(new StorageEvent('local-storage', { key })) |
166 | 173 | }) |
167 | 174 |
|
168 | | - useEffect(() => { |
169 | | - setStoredValue(readValue()) |
170 | | - // eslint-disable-next-line react-hooks/exhaustive-deps |
171 | | - }, [key]) |
| 175 | + const effectCallback = useCallback(() => setStoredValue(readValue()), []) |
| 176 | + |
| 177 | + if (!IS_SERVER && options.priority === 'max' ) { |
| 178 | + useLayoutEffect(effectCallback, [key]) |
| 179 | + } else { |
| 180 | + useEffect(effectCallback, [key]) |
| 181 | + } |
172 | 182 |
|
173 | 183 | const handleStorageChange = useCallback( |
174 | 184 | (event: StorageEvent | CustomEvent) => { |
|
0 commit comments