Skip to content

Commit

Permalink
Fix for roadmanfong#4 and roadmanfong#9 where apps get stuck on Persi…
Browse files Browse the repository at this point in the history
…stGate loading screens. Doesn't assume that PersistGate will be rendered before data is finished loading.
  • Loading branch information
smallsaucepan committed Mar 12, 2022
1 parent 1bbeae9 commit 24e1793
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 5 deletions.
10 changes: 10 additions & 0 deletions src/LoadManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ export class LoadManager {

onAllLoaded(callback: () => void) {
this.onAllLoadedCallback = callback

// Possible this could be called with a custom callback *after*
// loading has finished. Which means setLoaded (below) has finished
// being called and the custom callback would never be run.
// If loading has finished, execute callback immediately.
// https://github.com/roadmanfong/zustand-persist/issues/4
// https://github.com/roadmanfong/zustand-persist/issues/9
if (Object.values(this.loadStatusRecord).every(Boolean)) {
this.onAllLoadedCallback()
}
}

setLoaded(key: string) {
Expand Down
15 changes: 10 additions & 5 deletions src/PersistGate.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react'
import React, { useEffect, useState } from 'react'
import { getLoadManager } from './LoadManager'

export interface PersistGateProps {
Expand All @@ -11,10 +11,15 @@ export function PersistGate(props: PersistGateProps) {
const { children, loading = false, onBeforeLift } = props
const [isReady, setIsReady] = useState(false)

getLoadManager().onAllLoaded(async () => {
onBeforeLift && (await onBeforeLift())
setIsReady(true)
})
// Only need to call this once on initial render.
// https://github.com/roadmanfong/zustand-persist/issues/4
// https://github.com/roadmanfong/zustand-persist/issues/9
useEffect(() => {
getLoadManager().onAllLoaded(async () => {
onBeforeLift && (await onBeforeLift())
setIsReady(true)
})
}, [])

return <React.Fragment>{isReady ? children : loading}</React.Fragment>
}

0 comments on commit 24e1793

Please sign in to comment.