Reputation: 79
The following code (with some parts of it cut out for the sake of brevity) is working:
function AddressInputList({
isOpen,
inputValue,
highlightedIndex,
getItemProps,
getMenuProps
}: AutocompleteInputListProps) {
const [items, setItems] = useState<MarkerPoint[]>([])
const api = 'XXXX'
const fetchURL = `https://api.opencagedata.com/geocode/v1/json?key=${api}&q=${inputValue}&limit=5&pretty=1`
useEffect(() => {
async function fetchData() {
if (inputValue !== null && inputValue.length > 1) {
try {
const request = await axios.get(fetchURL)
const items = request.data.results.map((res: any) => {
return {
lat: res.geometry.lat,
lng: res.geometry.lng,
address: res.formatted
}
})
setItems(items)
} catch (error) {
console.error(error)
}
}
}
fetchData()
}, [inputValue])
return (/*Code cut out*/)
}
What I now would like to do is to refactor the code to make it more lean. So I will create a utility.ts
-file in which I have the fetchData
-function and I subsequently would like to import the fetchData
-function into the initial AddressInputList
-function:
utility.ts:
export async function fetchData(inputValue: string, fetchURL: string) {
if (inputValue !== null && inputValue.length > 1) {
try {
const request = await axios.get(fetchURL)
const items = request.data.results.map((res: any) => {
return {
lat: res.geometry.lat,
lng: res.geometry.lng,
address: res.formatted
}
})
setItems(items)
} catch (error) {
console.error(error)
}
}
}
Now my problem here is that I don't know how to make the useState-hook setItems
available in utility.ts
. I read somewhere that this could be done with props
but I'm not sure how this would look like. A short example would be highly appreciated!
Upvotes: 2
Views: 38
Reputation: 148
I guess you could just pass setItems as a callback function, as a parameter to your fetchData function.
fetchData(inputValue: string, fetchURL: string, setItems) {
...
}
Upvotes: 1
Reputation: 256
Just create a custom hook that would fetch data for you.
I wouldn't recommend to tie this hook to inputValue
so much. Also that .map formatting does not feel universal too.
export function useFetchData(inputValue: string, fetchURL: string) {
const [items,setItems] = useState([]);
useEffect(() => {
async function fetchData() {
if (inputValue !== null && inputValue.length > 1) {
try {
const request = await axios.get(fetchURL)
const items = request.data.results.map((res: any) => {
return {
lat: res.geometry.lat,
lng: res.geometry.lng,
address: res.formatted
}
})
setItems(items)
} catch (error) {
console.error(error)
}
}
}
}, [inputValue]);
return items;
}
After that you can use this custom hook like so
const items = useFetchData(inputValue, "/api/<endpoint>);
Upvotes: 2