Skip to content

Commit

Permalink
feat: pass config to the useVisitorData hook
Browse files Browse the repository at this point in the history
  • Loading branch information
borislobanov92 committed Mar 10, 2022
1 parent f922344 commit 750733a
Show file tree
Hide file tree
Showing 7 changed files with 585 additions and 546 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ function App() {
isLoading,
error,
getData,
} = useVisitorData({tag: 'subscription-form'}, false);
} = useVisitorData({tag: 'subscription-form'}, { immediate: false });
const [email, setEmail] = useState('')

if (isLoading) {
Expand Down
34 changes: 34 additions & 0 deletions __tests__/use-visitor-data.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { useVisitorData } from '../src'
import { renderHook } from '@testing-library/react-hooks'
import { createWrapper } from './helpers'

const testData = {
visitorId: 'abcdef123456',
}
const init = jest.fn()
const getVisitorData = jest.fn()

Expand All @@ -19,6 +22,10 @@ jest.mock('@fingerprintjs/fingerprintjs-pro-spa', () => {
})

describe('useVisitorData', () => {
beforeEach(() => {
getVisitorData.mockReset()
})

it('should provide the Fpjs context', async () => {
const wrapper = createWrapper()
const {
Expand All @@ -27,7 +34,34 @@ describe('useVisitorData', () => {
} = renderHook(() => useVisitorData(), { wrapper })
await waitForNextUpdate()
expect(current).toBeDefined()
})

it('should call getData on mount by default', async () => {
getVisitorData.mockImplementation(() => testData)

const wrapper = createWrapper()
const { waitForNextUpdate, result } = renderHook(() => useVisitorData(), { wrapper })
expect(result.current).toMatchObject(
expect.objectContaining({
isLoading: true,
data: undefined,
})
)
await waitForNextUpdate()
expect(init).toHaveBeenCalled()
expect(getVisitorData).toHaveBeenCalled()
expect(result.current).toMatchObject(
expect.objectContaining({
isLoading: false,
data: testData,
})
)
})

it("shouldn't call getData on mount if 'immediate' option is set to false", async () => {
const wrapper = createWrapper()
const { waitForNextUpdate } = renderHook(() => useVisitorData({}, { immediate: false }), { wrapper })
expect(() => waitForNextUpdate()).rejects.toThrow()
expect(getVisitorData).not.toHaveBeenCalled()
})
})
5 changes: 4 additions & 1 deletion examples/spa/src/shared/pages/SignInPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ function SignInPage() {
const [ignoreCache, setIgnoreCache] = useState(false)
const [extendedResult, setExtendedResult] = useState(false)

const { getData, data, isLoading, error } = useVisitorData({ extendedResult, tag, linkedId: login }, false)
const { getData, data, isLoading, error } = useVisitorData(
{ extendedResult, tag, linkedId: login },
{ immediate: false }
)

return (
<section className='body'>
Expand Down
1,040 changes: 516 additions & 524 deletions examples/spa/yarn.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"eslint": "^8.9.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.28.0",
"eslint-plugin-react": "7.27.0",
"eslint-plugin-react-hooks": "^4.3.0",
"jest": "^27.5.1",
"prettier": "^2.5.1",
Expand Down
32 changes: 21 additions & 11 deletions src/use-visitor-data.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import FpjsContext, { FpjsContextInterface, QueryResult, VisitorQueryContext } from './fpjs-context'
import { useCallback, useContext, useEffect, useMemo, useState } from 'react'
import { VisitorData, GetOptions } from '@fingerprintjs/fingerprintjs-pro-spa'
import { GetOptions, VisitorData } from '@fingerprintjs/fingerprintjs-pro-spa'

/**
* ```js
Expand All @@ -9,25 +9,26 @@ import { VisitorData, GetOptions } from '@fingerprintjs/fingerprintjs-pro-spa'
* * data,
* * isLoading,
* * error,
* * // A method to be called manually when the `immediate` flag is set to `false`:
* * // A method to be called manually when the `immediate` field in the config is set to `false`:
* * getData,
* * } = useVisitorData({ extended: true }, false);
* * } = useVisitorData({ extended: true }, { immediate: false });
* * ```
* *
* * Use the `useVisitorData` hook in your components to perform identification requests with the FingerprintJS API.
*
* @param config options for the `fp.get()` request
* @param immediate determines whether the `getData()` method will be called immediately after the hook mounts or not,
* @param getOptions options for the `fp.get()` request
* @param config config for the hook
*/
export function useVisitorData<TExtended extends boolean>(
config: GetOptions<TExtended> = {},
immediate = true
getOptions: GetOptions<TExtended> = {},
config: UseVisitorDataConfig = defaultUseVisitorDataConfig
): VisitorQueryContext<TExtended> {
const { extendedResult, timeout, tag, linkedId } = config ?? {}
const getOptions = useMemo(
const { extendedResult, timeout, tag, linkedId } = getOptions ?? {}
const memoizedOptions = useMemo(
() => ({ extendedResult, timeout, tag, linkedId }),
[extendedResult, timeout, tag, linkedId]
)
const { immediate } = config
const { getVisitorData } = useContext<FpjsContextInterface<TExtended>>(FpjsContext)

const initialState = { isLoading: false }
Expand All @@ -38,7 +39,7 @@ export function useVisitorData<TExtended extends boolean>(
try {
setState((state) => ({ ...state, isLoading: true }))

const result = await getVisitorData(getOptions, ignoreCache)
const result = await getVisitorData(memoizedOptions, ignoreCache)
setState((state) => ({ ...state, data: result, isLoading: false, error: undefined }))
return result
} catch (error) {
Expand All @@ -51,7 +52,7 @@ export function useVisitorData<TExtended extends boolean>(
setState((state) => (state.isLoading ? { ...state, isLoading: false } : state))
}
},
[getOptions, getVisitorData]
[memoizedOptions, getVisitorData]
)

useEffect(() => {
Expand All @@ -69,3 +70,12 @@ export function useVisitorData<TExtended extends boolean>(
error,
}
}

export interface UseVisitorDataConfig {
/**
* Determines whether the `getData()` method will be called immediately after the hook mounts or not
*/
immediate: boolean
}

const defaultUseVisitorDataConfig = { immediate: true }
16 changes: 8 additions & 8 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1548,22 +1548,22 @@ eslint-plugin-react-hooks@^4.3.0:
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz#318dbf312e06fab1c835a4abef00121751ac1172"
integrity sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA==

eslint-plugin-react@^7.28.0:
version "7.29.2"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.29.2.tgz#2d4da69d30d0a736efd30890dc6826f3e91f3f7c"
integrity sha512-ypEBTKOy5liFQXZWMchJ3LN0JX1uPI6n7MN7OPHKacqXAxq5gYC30TdO7wqGYQyxD1OrzpobdHC3hDmlRWDg9w==
eslint-plugin-react@7.27.0:
version "7.27.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.27.0.tgz#f952c76517a3915b81c7788b220b2b4c96703124"
integrity sha512-0Ut+CkzpppgFtoIhdzi2LpdpxxBvgFf99eFqWxJnUrO7mMe0eOiNpou6rvNYeVVV6lWZvTah0BFne7k5xHjARg==
dependencies:
array-includes "^3.1.4"
array.prototype.flatmap "^1.2.5"
doctrine "^2.1.0"
estraverse "^5.3.0"
jsx-ast-utils "^2.4.1 || ^3.0.0"
minimatch "^3.1.2"
minimatch "^3.0.4"
object.entries "^1.1.5"
object.fromentries "^2.0.5"
object.hasown "^1.1.0"
object.values "^1.1.5"
prop-types "^15.8.1"
prop-types "^15.7.2"
resolve "^2.0.0-next.3"
semver "^6.3.0"
string.prototype.matchall "^4.0.6"
Expand Down Expand Up @@ -2866,7 +2866,7 @@ min-indent@^1.0.0:
resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869"
integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==

minimatch@^3.0.4, minimatch@^3.1.2:
minimatch@^3.0.4:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
Expand Down Expand Up @@ -3155,7 +3155,7 @@ prompts@^2.0.1:
kleur "^3.0.3"
sisteransi "^1.0.5"

prop-types@^15.8.1:
prop-types@^15.7.2:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
Expand Down

0 comments on commit 750733a

Please sign in to comment.