1
- import { useEffect , useState } from 'react' ;
1
+ import { useEffect , useRef , useState } from 'react' ;
2
2
import * as Sentry from '@sentry/react' ;
3
3
4
4
import { loadDocs } from 'sentry/actionCreators/projects' ;
@@ -17,44 +17,44 @@ type Options = {
17
17
} ;
18
18
19
19
function useOnboardingDocs ( { docKeys, isPlatformSupported, project} : Options ) {
20
- const organization = useOrganization ( ) ;
21
20
const api = useApi ( ) ;
21
+ const organization = useOrganization ( ) ;
22
+
23
+ const loadingDocsRef = useRef < Record < string , boolean > > ( INITIAL_LOADING_DOCS ) ;
24
+ const docContentsRef = useRef < Record < string , string > > ( INITIAL_DOC_CONTENTS ) ;
22
25
23
- const [ loadingDocs , setLoadingDocs ] =
24
- useState < Record < string , boolean > > ( INITIAL_LOADING_DOCS ) ;
25
26
const [ docContents , setDocContents ] =
26
27
useState < Record < string , string > > ( INITIAL_DOC_CONTENTS ) ;
27
28
28
- const currentPlatform = project . platform
29
- ? platforms . find ( p => p . id === project . platform )
30
- : undefined ;
29
+ docContentsRef . current = docContents ;
31
30
32
31
useEffect ( ( ) => {
33
32
if ( ! isPlatformSupported ) {
34
- if ( loadingDocs !== INITIAL_LOADING_DOCS ) {
35
- setLoadingDocs ( INITIAL_LOADING_DOCS ) ;
33
+ if ( loadingDocsRef . current !== INITIAL_LOADING_DOCS ) {
34
+ loadingDocsRef . current = INITIAL_LOADING_DOCS ;
36
35
}
37
- if ( docContents !== INITIAL_DOC_CONTENTS ) {
36
+ if ( docContentsRef . current !== INITIAL_DOC_CONTENTS ) {
38
37
setDocContents ( INITIAL_DOC_CONTENTS ) ;
39
38
}
40
- return ;
39
+ return undefined ;
41
40
}
42
41
42
+ let cancelRequest = false ;
43
+
43
44
docKeys . forEach ( docKey => {
44
- if ( docKey in loadingDocs ) {
45
+ if ( docKey in loadingDocsRef . current ) {
45
46
// If a documentation content is loading, we should not attempt to fetch it again.
46
47
// otherwise, if it's not loading, we should only fetch at most once.
47
48
// Any errors that occurred will be captured via Sentry.
48
49
return ;
49
50
}
50
51
51
- const setLoadingDoc = ( loadingState : boolean ) =>
52
- setLoadingDocs ( prevState => {
53
- return {
54
- ...prevState ,
55
- [ docKey ] : loadingState ,
56
- } ;
57
- } ) ;
52
+ const setLoadingDoc = ( loadingState : boolean ) => {
53
+ loadingDocsRef . current = {
54
+ ...loadingDocsRef . current ,
55
+ [ docKey ] : loadingState ,
56
+ } ;
57
+ } ;
58
58
59
59
const setDocContent = ( docContent : string | undefined ) =>
60
60
setDocContents ( prevState => {
@@ -80,25 +80,33 @@ function useOnboardingDocs({docKeys, isPlatformSupported, project}: Options) {
80
80
platform : docKey as any ,
81
81
} )
82
82
. then ( ( { html} ) => {
83
- setDocContent ( html as string ) ;
83
+ if ( cancelRequest ) {
84
+ return ;
85
+ }
84
86
setLoadingDoc ( false ) ;
87
+ setDocContent ( html as string ) ;
85
88
} )
86
89
. catch ( error => {
90
+ if ( cancelRequest ) {
91
+ return ;
92
+ }
87
93
Sentry . captureException ( error ) ;
88
- setDocContent ( undefined ) ;
89
94
setLoadingDoc ( false ) ;
95
+ setDocContent ( undefined ) ;
90
96
} ) ;
91
97
} ) ;
92
- } , [
93
- currentPlatform ,
94
- docKeys ,
95
- isPlatformSupported ,
96
- api ,
97
- loadingDocs ,
98
- organization . slug ,
99
- project . slug ,
100
- docContents ,
101
- ] ) ;
98
+
99
+ return ( ) => {
100
+ cancelRequest = true ;
101
+ for ( const key of docKeys ) {
102
+ delete loadingDocsRef . current [ key ] ;
103
+ }
104
+ } ;
105
+ } , [ docKeys , isPlatformSupported , api , organization . slug , project ] ) ;
106
+
107
+ const currentPlatform = project . platform
108
+ ? platforms . find ( p => p . id === project . platform )
109
+ : undefined ;
102
110
103
111
if ( ! currentPlatform || ! isPlatformSupported ) {
104
112
return {
@@ -108,23 +116,20 @@ function useOnboardingDocs({docKeys, isPlatformSupported, project}: Options) {
108
116
} ;
109
117
}
110
118
111
- const isLoading = Boolean (
112
- docKeys ?. some ( key => {
113
- if ( key in loadingDocs ) {
114
- return ! ! loadingDocs [ key ] ;
119
+ const isLoading =
120
+ docKeys &&
121
+ docKeys . some ( key => {
122
+ if ( key in loadingDocsRef . current ) {
123
+ return ! ! loadingDocsRef . current [ key ] ;
115
124
}
116
125
return true ;
117
- } )
118
- ) ;
119
-
120
- const hasOnboardingContents = Boolean (
121
- docKeys ?. every ( key => typeof docContents [ key ] === 'string' )
122
- ) ;
126
+ } ) ;
123
127
124
128
return {
125
129
docKeys,
126
130
isLoading,
127
- hasOnboardingContents,
131
+ hasOnboardingContents :
132
+ docKeys && docKeys . every ( key => typeof docContents [ key ] === 'string' ) ,
128
133
docContents,
129
134
} ;
130
135
}
0 commit comments