Skip to content

Commit

Permalink
fix: ensure that "products" parameter is correctly passed into the cl…
Browse files Browse the repository at this point in the history
…ient
  • Loading branch information
TheUnderScorer committed Oct 28, 2022
1 parent 79ba9e3 commit 5c0dbd4
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 15 deletions.
40 changes: 39 additions & 1 deletion __tests__/use-visitor-data.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { useVisitorData } from '../src'
import { renderHook } from '@testing-library/react'
import { render, renderHook } from '@testing-library/react'
import { actWait, createWrapper } from './helpers'
import { act } from 'react-dom/test-utils'
import { useState } from 'react'
import userEvent from '@testing-library/user-event'

const testData = {
visitorId: 'abcdef123456',
Expand Down Expand Up @@ -82,6 +84,7 @@ describe('useVisitorData', () => {

await actWait(500)

expect(getVisitorData).toHaveBeenCalledTimes(1)
expect(getVisitorData).toHaveBeenCalledWith({}, true)
})

Expand All @@ -95,6 +98,41 @@ describe('useVisitorData', () => {
})
})

expect(getVisitorData).toHaveBeenCalledTimes(1)
expect(getVisitorData).toHaveBeenCalledWith({}, false)
})

it('should re-fetch data when options change if "immediate" is set to true', async () => {
const Component = () => {
const [extended, setExtended] = useState(false)
const { data } = useVisitorData({ extendedResult: extended }, { immediate: true })

return (
<>
<button onClick={() => setExtended((prev) => !prev)}>Change options</button>
<pre>{JSON.stringify(data)}</pre>
</>
)
}

const Wrapper = createWrapper()

const { container } = render(
<Wrapper>
<Component />
</Wrapper>
)

await actWait(1000)

act(() => {
userEvent.click(container.querySelector('button')!)
})

await actWait(1000)

expect(getVisitorData).toHaveBeenCalledTimes(2)
expect(getVisitorData).toHaveBeenNthCalledWith(1, { extendedResult: false }, undefined)
expect(getVisitorData).toHaveBeenNthCalledWith(2, { extendedResult: true }, undefined)
})
})
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
},
"homepage": "https://github.com/fingerprintjs/fingerprintjs-pro-react#readme",
"dependencies": {
"@fingerprintjs/fingerprintjs-pro-spa": "^0.5.0"
"@fingerprintjs/fingerprintjs-pro-spa": "^0.5.0",
"fast-deep-equal": "3.1.3"
},
"devDependencies": {
"@commitlint/cli": "^17.0.3",
Expand Down
31 changes: 19 additions & 12 deletions src/use-visitor-data.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import FpjsContext, { FpjsContextInterface, GetDataOptions, QueryResult, VisitorQueryContext } from './fpjs-context'
import { useCallback, useContext, useEffect, useMemo, useState } from 'react'
import { useCallback, useContext, useEffect, useState } from 'react'
import { GetOptions, VisitorData } from '@fingerprintjs/fingerprintjs-pro-spa'
import { usePrevious } from './utils/use-previous'
import deepEquals from 'fast-deep-equal'

export type UseVisitorDataOptions<TExtended extends boolean> = GetOptions<TExtended> & Partial<GetDataOptions>

/**
* @example
* ```js
Expand All @@ -24,23 +27,25 @@ export function useVisitorData<TExtended extends boolean>(
getOptions: UseVisitorDataOptions<TExtended> = {},
config: UseVisitorDataConfig = defaultUseVisitorDataConfig
): VisitorQueryContext<TExtended> {
const { extendedResult, timeout, tag, linkedId } = getOptions ?? {}
const memoizedOptions = useMemo(
() => ({ extendedResult, timeout, tag, linkedId }),
[extendedResult, timeout, tag, linkedId]
)
const previousGetOptions = usePrevious(getOptions)

const { immediate } = config
const { getVisitorData } = useContext<FpjsContextInterface<TExtended>>(FpjsContext)

const initialState = { isLoading: false }
const [state, setState] = useState<QueryResult<VisitorData<TExtended>>>(initialState)

const getData = useCallback<VisitorQueryContext<TExtended>['getData']>(
async ({ ignoreCache = getOptions.ignoreCache } = {}) => {
async ({ ignoreCache } = {}) => {
try {
setState((state) => ({ ...state, isLoading: true }))

const result = await getVisitorData(memoizedOptions, ignoreCache)
const { ignoreCache: defaultIgnoreCache, ...getVisitorDataOptions } = getOptions

const result = await getVisitorData(
getVisitorDataOptions ?? {},
typeof ignoreCache === 'boolean' ? ignoreCache : defaultIgnoreCache
)
setState((state) => ({ ...state, data: result, isLoading: false, error: undefined }))
return result
} catch (error) {
Expand All @@ -53,14 +58,16 @@ export function useVisitorData<TExtended extends boolean>(
setState((state) => (state.isLoading ? { ...state, isLoading: false } : state))
}
},
[getOptions.ignoreCache, getVisitorData, memoizedOptions]
[getOptions, getVisitorData]
)

useEffect(() => {
if (immediate) {
getData()
if (immediate && (!previousGetOptions || !deepEquals(getOptions, previousGetOptions))) {
getData().catch((error) => {
console.error(`Failed to fetch visitor data on mount: ${error}`)
})
}
}, [getData, immediate])
}, [immediate, getData, previousGetOptions, getOptions])

const { isLoading, data, error } = state

Expand Down
11 changes: 11 additions & 0 deletions src/utils/use-previous.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { useEffect, useRef } from 'react'

export function usePrevious<T>(value: T) {
const ref = useRef<T>()

useEffect(() => {
ref.current = value
}, [value])

return ref.current
}
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3603,7 +3603,7 @@ external-editor@^3.0.3:
iconv-lite "^0.4.24"
tmp "^0.0.33"

fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
fast-deep-equal@3.1.3, fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
Expand Down

0 comments on commit 5c0dbd4

Please sign in to comment.