@navinc/base-react-components
Version:
Nav's Pattern Library
104 lines (91 loc) • 3.21 kB
JavaScript
import React, { useState, useEffect, useRef, createContext, useContext, useCallback } from 'react'
import { initialize } from 'launchdarkly-js-client-sdk'
import isEqual from 'lodash.isequal'
const LaunchDarklyContext = createContext({})
export const LaunchDarklyProvider = ({
clientSideID,
context,
options,
children,
LoadingContent,
onTimeout = () => {},
}) => {
const ldclient = useRef()
const [flags, setFlags] = useState([])
const [isLoading, setIsLoading] = useState(true)
const [hasTimedOut, setHasTimedOut] = useState(false)
const [isInitialized, setIsInitialized] = useState(false)
const [lastContext, setLastContext] = useState(context)
const trackMetric = ldclient.current?.track
const whichVariation = ldclient.current?.variation
const trackOfferReferral = useCallback((offer = {}, additionalInfo = {}) => {
const { matchFactorScore, mfSource, offerCategory, offerId, rtid, order } = offer
const payload = {
matchFactorScore,
mfSource,
offerCategory,
offerId,
rtid,
order,
...additionalInfo,
}
if (ldclient.current)
ldclient.current.waitForInitialization().then(() => ldclient.current.track('offer_referral', payload))
}, [])
useEffect(() => {
setTimeout(() => {
if (isLoading) {
setIsLoading(false)
setHasTimedOut(true)
// should be a bugsnag call
onTimeout()
}
}, 500)
})
useEffect(() => {
if (context && clientSideID && !isInitialized && !hasTimedOut)
ldclient.current = initialize(clientSideID, context, options)
else if (!isInitialized) console.warn('Please provide a user object and clientSideID')
}, [clientSideID, context, isInitialized, hasTimedOut, options])
useEffect(() => {
if (ldclient.current && context && !isInitialized)
ldclient.current.waitForInitialization().then(() => {
setIsInitialized(true)
setIsLoading(false)
setFlags(ldclient.current.allFlags())
})
}, [isInitialized, context])
// TODO Not sure this is being used
useEffect(() => {
if (!isEqual(context, lastContext) && isInitialized) {
setLastContext(context)
ldclient.current.identify(context)
}
}, [context, lastContext, ldclient, isInitialized])
// TODO add listener for on change to update flags state
return (
<LaunchDarklyContext.Provider
value={{
flags,
isLoading,
isInitialized,
trackMetric,
trackOfferReferral,
whichVariation,
ldclient: ldclient.current,
}}
>
{isLoading && !!LoadingContent ? <LoadingContent /> : children}
</LaunchDarklyContext.Provider>
)
}
export const useLaunchDarkly = () => {
const { flags, isLoading, isInitialized, trackMetric, trackOfferReferral, whichVariation, ldclient } =
useContext(LaunchDarklyContext)
const hasProvider = !!ldclient
return { flags, isLoading, isInitialized, trackMetric, trackOfferReferral, whichVariation, ldclient, hasProvider }
}
export const withLaunchDarkly = (Component) => (props) => {
const { whichVariation } = useLaunchDarkly()
return <Component whichVariation={whichVariation} {...props} />
}