1
1
import { ReloadOptions , router } from '@inertiajs/core'
2
- import { createElement , ReactElement , useCallback , useEffect , useRef , useState } from 'react'
2
+ import { createElement , ReactElement , useCallback , useEffect , useMemo , useRef } from 'react'
3
+ import usePage from './usePage'
3
4
4
5
interface WhenVisibleProps {
5
6
children : ReactElement | number | string
@@ -16,15 +17,29 @@ const WhenVisible = ({ children, data, params, buffer, as, always, fallback }: W
16
17
as = as ?? 'div'
17
18
fallback = fallback ?? null
18
19
19
- const [ loaded , setLoaded ] = useState ( false )
20
+ const loaded = useRef < boolean > ( false )
20
21
const hasFetched = useRef < boolean > ( false )
21
22
const fetching = useRef < boolean > ( false )
22
23
const ref = useRef < HTMLDivElement > ( null )
24
+ const pageProps = usePage ( ) . props
25
+ const keys = useMemo ( ( ) => ( params ? ( params . only ?? [ ] ) : Array . isArray ( data ) ? data : [ data ] ) , [ data , params ] )
26
+
27
+ loaded . current = useMemo ( ( ) => {
28
+ if ( fetching . current || ! loaded . current ) return loaded . current
29
+
30
+ const propsLoaded = ! keys . length ? true : keys . every ( ( key ) => pageProps [ key ] !== undefined )
31
+
32
+ if ( ! propsLoaded ) {
33
+ hasFetched . current = false
34
+ }
35
+
36
+ return propsLoaded
37
+ } , [ pageProps , keys ] )
23
38
24
39
const getReloadParams = useCallback < ( ) => Partial < ReloadOptions > > ( ( ) => {
25
40
if ( data ) {
26
41
return {
27
- only : ( Array . isArray ( data ) ? data : [ data ] ) as string [ ] ,
42
+ only : keys ,
28
43
}
29
44
}
30
45
@@ -33,10 +48,10 @@ const WhenVisible = ({ children, data, params, buffer, as, always, fallback }: W
33
48
}
34
49
35
50
return params
36
- } , [ params , data ] )
51
+ } , [ params , data , keys ] )
37
52
38
53
useEffect ( ( ) => {
39
- if ( ! ref . current ) {
54
+ if ( ! ref . current || loaded . current ) {
40
55
return
41
56
}
42
57
@@ -66,7 +81,7 @@ const WhenVisible = ({ children, data, params, buffer, as, always, fallback }: W
66
81
reloadParams . onStart ?.( e )
67
82
} ,
68
83
onFinish : ( e ) => {
69
- setLoaded ( true )
84
+ loaded . current = true
70
85
fetching . current = false
71
86
reloadParams . onFinish ?.( e )
72
87
@@ -86,20 +101,20 @@ const WhenVisible = ({ children, data, params, buffer, as, always, fallback }: W
86
101
return ( ) => {
87
102
observer . disconnect ( )
88
103
}
89
- } , [ ref , getReloadParams , buffer ] )
104
+ } , [ ref , getReloadParams , buffer , loaded . current ] )
90
105
91
- if ( always || ! loaded ) {
106
+ if ( always || ! loaded . current ) {
92
107
return createElement (
93
108
as ,
94
109
{
95
110
props : null ,
96
111
ref,
97
112
} ,
98
- loaded ? children : fallback ,
113
+ loaded . current ? children : fallback ,
99
114
)
100
115
}
101
116
102
- return loaded ? children : null
117
+ return loaded . current ? children : null
103
118
}
104
119
105
120
WhenVisible . displayName = 'InertiaWhenVisible'
0 commit comments