Keep optionality of API, but try and maintain hook order.

Signed-off-by: Eric Peterson <ericpeterson@spotify.com>
This commit is contained in:
Eric Peterson
2021-10-04 15:59:27 +02:00
parent f2e9fbf2b5
commit decaaae1ed
2 changed files with 29 additions and 2 deletions
@@ -23,6 +23,17 @@ jest.mock('../apis');
const mocked = (f: Function) => f as jest.Mock;
describe('useAnalytics', () => {
it('returns tracker with no implementation defined', () => {
// Simulate useApi() throwing an error.
mocked(useApi).mockImplementation(() => {
throw new Error();
});
// Result should still have a captureEvent method.
const { result } = renderHook(() => useAnalytics());
expect(result.current.captureEvent).toBeDefined();
});
it('returns tracker from defined analytics api', () => {
const captureEvent = jest.fn();
@@ -15,17 +15,33 @@
*/
import { useAnalyticsContext } from './AnalyticsContext';
import { analyticsApiRef, AnalyticsTracker, useApi } from '../apis';
import {
analyticsApiRef,
AnalyticsTracker,
AnalyticsApi,
useApi,
} from '../apis';
import { useRef } from 'react';
import { Tracker } from './Tracker';
function useAnalyticsApi(): AnalyticsApi {
try {
return useApi(analyticsApiRef);
} catch {
return { captureEvent: () => {} };
}
}
/**
* Get a pre-configured analytics tracker.
*/
export function useAnalytics(): AnalyticsTracker {
const trackerRef = useRef<Tracker | null>(null);
const analyticsApi = useApi(analyticsApiRef);
const context = useAnalyticsContext();
// Our goal is to make this API truly optional for any/all consuming code
// (including tests). This hook runs last to ensure hook order is, as much as
// possible, maintained.
const analyticsApi = useAnalyticsApi();
function getTracker(): Tracker {
if (trackerRef.current === null) {