このコミットが含まれているのは:
2026-07-18 20:03:26 +09:00
コミット 8f66ee8059
2個のファイルの変更、59行の追加、58行の削除
+18 -17
ファイルの表示
@@ -7,7 +7,7 @@ import {
useRef,
useState,
} from 'react'
import { useBlocker, useLocation } from 'react-router-dom'
import { useBlocker } from 'react-router-dom'
import { useDialogue } from '@/lib/dialogues/useDialogue'
@@ -34,7 +34,6 @@ const UnsavedChangesGuardContext =
export const UnsavedChangesGuardProvider: FC<PropsWithChildren> = ({ children }) => {
const dialogue = useDialogue ()
const location = useLocation ()
const sourcesRef = useRef (new Map<symbol, UnsavedChangesSource> ())
const bypassNextNavigationRef = useRef (false)
const [revision, setRevision] = useState (0)
@@ -68,12 +67,19 @@ export const UnsavedChangesGuardProvider: FC<PropsWithChildren> = ({ children })
[sources],
)
const hasUnsavedChanges = dirtySources.length > 0
const blocker = useBlocker (
useCallback (
() => hasUnsavedChanges && !(bypassNextNavigationRef.current),
[hasUnsavedChanges],
),
)
const shouldBlock = useCallback (() => {
if (!(hasUnsavedChanges))
return false
if (bypassNextNavigationRef.current)
{
bypassNextNavigationRef.current = false
return false
}
return true
}, [hasUnsavedChanges])
const blocker = useBlocker (shouldBlock)
const discardDirtyChanges = useCallback (async (): Promise<boolean> => {
if (!(hasUnsavedChanges))
@@ -93,8 +99,6 @@ export const UnsavedChangesGuardProvider: FC<PropsWithChildren> = ({ children })
if (!(confirmed))
return false
bypassNextNavigationRef.current = true
try
{
for (const source of dirtySources)
@@ -102,7 +106,6 @@ export const UnsavedChangesGuardProvider: FC<PropsWithChildren> = ({ children })
}
catch
{
bypassNextNavigationRef.current = false
return false
}
@@ -139,10 +142,6 @@ export const UnsavedChangesGuardProvider: FC<PropsWithChildren> = ({ children })
}
}, [blocker, discardDirtyChanges])
useEffect (() => {
bypassNextNavigationRef.current = false
}, [location.hash, location.pathname, location.search])
useEffect (() => {
if (!(hasUnsavedChanges))
return
@@ -183,14 +182,16 @@ export const useUnsavedChangesGuard = (
if (context == null)
throw new Error ('UnsavedChangesGuardProvider が必要です.')
const { registerUnsavedChangesSource } = context
useEffect (() => {
if (options == null)
return
return context.registerUnsavedChangesSource ({
return registerUnsavedChangesSource ({
dirty: options.dirty,
discard: options.onDiscard ?? (() => undefined) })
}, [context, options?.dirty, options?.onDiscard])
}, [options?.dirty, options?.onDiscard, registerUnsavedChangesSource])
return context
}