Here is a very basic search by title query on a public API. In my actual app my API calls are under services.js files so I'm trying to do this where my API call is not inside the react component.
https://codesandbox.io/s/elastic-pond-pghylu?file=/src/App.js
import * as React from "react";
import axios from "axios";
// services.js
const fetchPhotos = async (query) => {
const { data } = await axios.get(
`https://jsonplaceholder.typicode.com/photos?title_like=${query}`
);
return data;
};
export default function App() {
const [photos, setPhotos] = React.useState([]);
const [searchTerm, setSearchTerm] = React.useState("");
const fetch = React.useCallback(async () => {
const data = await fetchPhotos(searchTerm);
setPhotos(data);
}, [searchTerm]);
React.useEffect(() => {
fetch();
}, [fetch]);
return (
<div>
<input
type="text"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
<div>
{photos?.map((photo) => (
<div>{JSON.stringify(photo.title)}</div>
))}
</div>
</div>
);
}
The problem with my code is this (too many api calls while im typing):
My attempt to fix this
for example, I tried this: (I wrapped debounce onto my fetchPhotos function)
import {debounce} from 'lodash';
// services.js
const fetchPhotos = debounce(async (query) => {
const { data } = await axios.get(
`https://jsonplaceholder.typicode.com/photos?title_like=${query}`
);
return data;
}, 500);
however now fetchphotos returns undefined always?
You can make use of useCallback
so that the debounced
(fetchPhotos) will have same function across re-renders
import * as React from "react";
import axios from "axios";
import { debounce } from "lodash";
// services.js
export default function App() {
const [photos, setPhotos] = React.useState([]);
const [searchTerm, setSearchTerm] = React.useState("");
async function fetchData(searchTerm) {
const data = await axios.get(
`https://jsonplaceholder.typicode.com/photos?title_like=${searchTerm}`
);
setPhotos(data.data);
}
const debounced = React.useCallback(debounce(fetchData, 500), []);
React.useEffect(() => {
// for the first render load
fetchData("");
}, []);
return (
<div>
<input
type="text"
value={searchTerm}
onChange={(e) => {
setSearchTerm(e.target.value);
debounced(e.target.value, 1000);
}}
/>
<div>
{photos?.map((photo) => (
<div key={photo.id}>{JSON.stringify(photo.title)}</div>
))}
</div>
</div>
);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With