Skip to content

Commit 9f7d82b

Browse files
committed
fix: correctly instantiate new API client if options change
before this change a new client would not be instantiated when some options change, as useMemo doesn’t deep compare the values in the dependencies array. The workaround to use state for it didn’t actually work. Also useMemo is meant to only be used as a performance improvement, which in this case is not enough because rely on the internal state of the API client so we don’t want to recreate it unless its options change.
1 parent efc670b commit 9f7d82b

File tree

3 files changed

+51
-13
lines changed

3 files changed

+51
-13
lines changed

package-lock.json

Lines changed: 40 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
"lodash.throttle": "^4.1.1",
1717
"lodash.unescape": "^4.0.1",
1818
"react": "^17.0.2",
19-
"react-dom": "^17.0.2"
19+
"react-dom": "^17.0.2",
20+
"use-deep-compare-effect": "^1.8.1"
2021
},
2122
"devDependencies": {
2223
"esbuild": "^0.14.38",

src/autocomplete/autocomplete.js

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import React, { useState, useMemo, useCallback, useRef, useEffect } from 'react'
1+
import React, { useState, useCallback, useRef, useEffect } from 'react'
2+
import useDeepCompareEffect from 'use-deep-compare-effect'
23
import { useCombobox } from 'downshift'
34
import { createAutocomplete } from '@geocodeearth/core-js'
45
import throttle from 'lodash.throttle'
@@ -31,6 +32,7 @@ export default ({
3132
const [results, setResults] = useState(emptyResults)
3233
const [isLoading, setIsLoading] = useState(false)
3334
const inputRef = useRef()
35+
const autocomplete = useRef()
3436

3537
// call user-supplied onFeatures callback
3638
useEffect(() => {
@@ -39,22 +41,18 @@ export default ({
3941
}
4042
}, [results])
4143

42-
// setting params & options as state so they can be passed to useMemo as dependencies,
43-
// which doesn’t work if they’re just objects as the internal comparison fails
44-
const [apiParams, setApiParams] = useState(params)
45-
const [apiOptions, setApiOptions] = useState(options)
46-
47-
// Geocode Earth Autocomplete Client
48-
const autocomplete = useMemo(() => {
49-
return createAutocomplete(apiKey, params, {
44+
// deep compare is used to to only instantiate a new autocomplete API client if
45+
// required properties for it change
46+
useDeepCompareEffect(() => {
47+
autocomplete.current = createAutocomplete(apiKey, params, {
5048
...options,
5149
client: `ge-autocomplete${typeof VERSION !== 'undefined' ? `-${VERSION}` : ''}`
5250
})
53-
}, [apiKey, apiParams, apiOptions])
51+
}, [apiKey, params, options])
5452

5553
// search queries the autocomplete API
5654
const search = useCallback(text => {
57-
autocomplete(text).then(({ features, discard }) => {
55+
autocomplete.current(text).then(({ features, discard }) => {
5856
setIsLoading(false)
5957

6058
if (discard || inputRef.current.value !== text) {

0 commit comments

Comments
 (0)