Skip to content

Commit c5a6e9c

Browse files
committed
refactor(useSegment): introduce new prop to get rid of undefined shouldLoad status
1 parent 6e9ca1b commit c5a6e9c

File tree

2 files changed

+50
-19
lines changed

2 files changed

+50
-19
lines changed

packages/use-segment/src/__tests__/index.tsx

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ const wrapper =
4646
({
4747
settings,
4848
initOptions,
49+
isOptionsLoaded,
4950
onError,
5051
onEventError,
5152
events = defaultEvents,
@@ -54,6 +55,7 @@ const wrapper =
5455
<SegmentProvider
5556
settings={settings}
5657
initOptions={initOptions}
58+
isOptionsLoaded={isOptionsLoaded}
5759
onError={onError}
5860
onEventError={onEventError}
5961
events={events}
@@ -82,7 +84,7 @@ describe('segment hook', () => {
8284
console.error = orignalConsoleError
8385
})
8486

85-
it('useSegment should not be ready and not load when options are loading', () => {
87+
it('useSegment should not be ready and not load by default', () => {
8688
const mock = jest
8789
.spyOn(AnalyticsBrowser, 'load')
8890
.mockResolvedValue([{} as Analytics, {} as Context])
@@ -132,6 +134,7 @@ describe('segment hook', () => {
132134
events: defaultEvents,
133135
initOptions: { integrations: { All: false } },
134136
settings: { writeKey: 'sample ' },
137+
isOptionsLoaded: true,
135138
}),
136139
})
137140
expect(mock).toHaveBeenCalledTimes(0)
@@ -155,6 +158,7 @@ describe('segment hook', () => {
155158
},
156159
},
157160
settings: { writeKey: 'sample ' },
161+
isOptionsLoaded: true,
158162
}),
159163
})
160164

@@ -182,6 +186,7 @@ describe('segment hook', () => {
182186
},
183187
},
184188
settings: { writeKey: 'sample ' },
189+
isOptionsLoaded: true,
185190
}),
186191
})
187192

@@ -193,7 +198,7 @@ describe('segment hook', () => {
193198
expect(result.current.isAnalyticsReady).toBe(true)
194199
})
195200

196-
it('Provider should load with key', async () => {
201+
it('Provider should not load when options are not loaded', async () => {
197202
const mock = jest
198203
.spyOn(AnalyticsBrowser, 'load')
199204
.mockResolvedValue([{} as Analytics, {} as Context])
@@ -205,11 +210,35 @@ describe('segment hook', () => {
205210
events: defaultEvents,
206211
settings,
207212
initOptions: {},
213+
isOptionsLoaded: false,
214+
}),
215+
})
216+
217+
expect(mock).toHaveBeenCalledTimes(0)
218+
219+
await waitFor(() => {
220+
expect(result.current.analytics).toStrictEqual(undefined)
221+
})
222+
expect(result.current.isAnalyticsReady).toBe(false)
223+
})
224+
225+
it('Provider should load with key', async () => {
226+
const mock = jest
227+
.spyOn(AnalyticsBrowser, 'load')
228+
.mockResolvedValue([{} as Analytics, {} as Context])
229+
230+
const settings = { writeKey: 'helloworld' }
231+
232+
const { result } = renderHook(() => useSegment<DefaultEvents>(), {
233+
wrapper: wrapper({
234+
events: defaultEvents,
235+
settings,
236+
isOptionsLoaded: true,
208237
}),
209238
})
210239

211240
expect(mock).toHaveBeenCalledTimes(1)
212-
expect(mock).toHaveBeenCalledWith(settings, {})
241+
expect(mock).toHaveBeenCalledWith(settings, undefined)
213242

214243
await waitFor(() => {
215244
expect(result.current.analytics).toStrictEqual({})
@@ -228,12 +257,12 @@ describe('segment hook', () => {
228257
wrapper: wrapper({
229258
events: defaultEvents,
230259
settings,
231-
initOptions: {},
260+
isOptionsLoaded: true,
232261
}),
233262
})
234263

235264
expect(mock).toHaveBeenCalledTimes(1)
236-
expect(mock).toHaveBeenCalledWith(settings, {})
265+
expect(mock).toHaveBeenCalledWith(settings, undefined)
237266

238267
await waitFor(() => {
239268
expect(result.current.analytics).toStrictEqual({})
@@ -253,12 +282,12 @@ describe('segment hook', () => {
253282
events: defaultEvents,
254283
onError,
255284
settings,
256-
initOptions: {},
285+
isOptionsLoaded: true,
257286
}),
258287
})
259288

260289
expect(mock).toHaveBeenCalledTimes(1)
261-
expect(mock).toHaveBeenCalledWith(settings, {})
290+
expect(mock).toHaveBeenCalledWith(settings, undefined)
262291

263292
await waitForExpect(() => {
264293
expect(onError).toHaveBeenCalledTimes(1)
@@ -285,7 +314,7 @@ describe('segment hook', () => {
285314
onError,
286315
onEventError,
287316
settings,
288-
initOptions: {},
317+
isOptionsLoaded: true,
289318
}),
290319
})
291320

@@ -317,6 +346,7 @@ describe('segment hook', () => {
317346
events: defaultEvents,
318347
initOptions,
319348
settings,
349+
isOptionsLoaded: true,
320350
}),
321351
})
322352

packages/use-segment/src/useSegment.tsx

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export function useSegment<T extends Events>(): SegmentContextInterface<T> {
4141
export type SegmentProviderProps<T> = {
4242
settings?: AnalyticsBrowserSettings
4343
initOptions?: InitOptions
44+
isOptionsLoaded?: boolean
4445
onError?: (err: Error) => void
4546
onEventError?: OnEventError
4647
events: T
@@ -53,6 +54,7 @@ function SegmentProvider<T extends Events>({
5354
children,
5455
settings,
5556
initOptions,
57+
isOptionsLoaded = false,
5658
onError,
5759
onEventError,
5860
events,
@@ -63,26 +65,25 @@ function SegmentProvider<T extends Events>({
6365
)
6466

6567
const shouldLoad = useMemo(() => {
66-
if (settings !== undefined && initOptions !== undefined) {
67-
const hasNoIntegrationsSettings = !initOptions.integrations
68-
const isAllEnabled = !!initOptions.integrations?.All
68+
if (isOptionsLoaded) {
69+
const hasNoIntegrationsSettings = !initOptions?.integrations
70+
const isAllEnabled = !!initOptions?.integrations?.All
6971
const isAnyIntegrationEnabled = Object.values(
70-
initOptions.integrations ?? {},
72+
initOptions?.integrations ?? {},
7173
).reduce<boolean>((acc, integration) => !!acc || !!integration, false)
7274

7375
return (
74-
!!settings.writeKey &&
76+
!!settings?.writeKey &&
7577
(hasNoIntegrationsSettings || isAllEnabled || isAnyIntegrationEnabled)
7678
)
7779
}
7880

79-
// If options or settings are undefined, we don't know if we should load or not
80-
// (For example, in case segment integrations are still loading)
81-
return undefined
82-
}, [initOptions, settings])
81+
// If options are not loaded, we should not load
82+
return false
83+
}, [initOptions?.integrations, isOptionsLoaded, settings?.writeKey])
8384

8485
useDeepCompareEffectNoCheck(() => {
85-
if (shouldLoad === true && settings) {
86+
if (isOptionsLoaded && shouldLoad && settings) {
8687
AnalyticsBrowser.load(settings, initOptions)
8788
.then(([res]) => {
8889
setAnalytics(res)
@@ -93,7 +94,7 @@ function SegmentProvider<T extends Events>({
9394
.finally(() => {
9495
setIsAnalyticsReady(true)
9596
})
96-
} else if (shouldLoad === false) {
97+
} else if (isOptionsLoaded && !shouldLoad) {
9798
// When user has refused tracking, set ready anyway
9899
setIsAnalyticsReady(true)
99100
}

0 commit comments

Comments
 (0)