i want to send request to api when the page is loaded - reactjs

I have an api and I want to request to api when the page loads. I use useEffect, but useEffect always makes requests and I don't want it. How can I make it possible to request only 1 time when the page loads?
My code
useEffect(() => {
fetch("API_URL")
.then(response=>response.json())
.then(data=>setDatas(data.reverse()))
})

Try this
useEffect(() => {
fetch("API_URL")
.then(response=>response.json())
.then(data=>setDatas(data.reverse()))
}, [])
The [] at the end defines the dependency for the useEffect hook. So an empty array defines no dependency and thus will trigger only once the component/screen loads.

Related

React app keeps sending continuous HTTP requests

I have a page that displays data fetched from a MongoDb through API, in this page, you can modify the data and after that, the page will render again to display the new data. But inspecting the network requests I noticed my react app sends an infinite number of requests, which obviously slows down everything. I read this is caused by this snippet of code:
useEffect(() => {
fetchData();
}, [users]);
I also read I must empty the dependencies array of the useEffect, but If I do so, the page will not re-render if the data changes (for example after inserting a new record in the db).
This is the function I use to get the data from the db:
const [users, setUsers] = useState([]);
async function fetchData() {
const res = await fetch("http://localhost:8000/users/");
if (res.status === 401) {
console.log(res.json);
} else {
setUsers(await res.json());
}
}
How can I fix this? Thanks.
You created an infinite loop:
fetchData calls setUsers, which sets users. The effect reacts to changes to users, and calls fetchData again. ♾️
I don't know your exact use case, but one solution would be to only call fetchData when an actual user interaction has happend in your app that makes you want to fetch new data.

using multiple useEffect in order. fetching API after fetching the location

this is my first time using react. im working on a basic weather app.
i have a problem with using multiple useEffect hook in order. i need to fetch both the geolocation and then the weather APP api in order when the page load.
but i the location keep returning null, here's the code
useEffect(()=>{
navigator.geolocation.getCurrentPosition((position) => {
setLatitude(position.coords.latitude)
setLongitude(position.coords.longitude)
});
},[])
useEffect(()=> {
axios.get(`${api.base}weather?lat=${latitude}&lon=${longitude}&units=metric&appid=${api.key}`).then
((response) => {
console.log(response.data)
})
},[])
any solution will be appreciated. thank you
For this you could make the second useEffect dependent on your latitude and longitude states:
useEffect(()=>{
axios.get(`${api.base}weather?lat=${latitude}&lon=${longitude}&units=metric&appid=${api.key}`).then
((response) => {
console.log(response.data)
})
},[latitute, longitude])
This will call the useEffect every Time the latitude or longitude states have changed.
Your useEffects are both running asynchronously after the first render. If you need them to be ordered, then you should run them together in the same useEffect and add your code to fetch the response within the success callback of getCurrentPosition.
See this example:
useEffect(() => {
const fetchData = async() => {
navigator.geolocation.getCurrentPosition((position) => {
setLatitude(position.coords.latitude)
setLongitude(position.coords.longitude);
const response = await axios.get(`${api.base}weatherlat=${position.coords.latitude}&lon=${position.coords.longitude}&units=metric&appid=${api.key}`);
});
});
}, []);
Note: setState is also asynchronous, hence why we use the return position directly for the axios fetch request.
An alternative to this is, as the other answer mentioned, having your second useEffect use [latitude, longitude] in the deps array but if you don't want to constantly fetch weather API data every single time the lat/long changes, then you can just do it this way to run this once on initial component mount.

React multiple http calls when navigating the application using the URL

I have a component which has filtering, searching and pagination capabilities. What I'm trying is to create a queryString and attach to the URL such that I can later copy and paste it in another browser so that I can reuse the filters.
To extract the query params from the URL I'm using the useLocation hook
const useQuery = () => new URLSearchParams(useLocation().search);
const pageNo = useQuery().get('page') ?? 1;
I'm using the useEffect hook to track for changes of the page query parameter value, and dispatch an action which will update the pageNo in the state object of my reducer.
React.useEffect(() => {
dispatch({
type: actionDescriptor.CHANGE_PAGE,
payload: pageNo
});
}, [pageNo]);
I have another useEffect hook which handles the fetch of the data, and gets triggered when the pageNo changes. I'm using the useNavigate to create and navigate to the new location if the http call was successful
const nav = useNavigate();
React.useEffect(() => {
(async function get() {
const response = // make http call and get response
if (response.status === 200) {
dispatch({
type: actionDescriptor.FETCH_SUCCESS,
payload: {
data: response.data['value'],
}
});
nav (`/data?page=${state.pageNo}`);
}
/// handle error
}
})();
}, [state.pageNo, state.pageSize, state.filter]);
When I'm navigating using the UI, selecting a different page for example, all works well, there is a single http call, the browser url is updated as expected (e.g. localhost/mydata?page=2). If however I'm copying the url and paste it in another window, it makes two http calls, and renders the dom twice. What might be the cause for this?
my guess is due to the parameters you are listening on state.pageNo, state.pageSize, state.filter. I'm assuming all of these are null/empty at the beginning of your app. Once you copied and pasted the url, two of these parameters will change which will cause the useEffect to be called twice.
put in a console.log in the useEffect to confirm that. Once that's confirmed, I would re-examine the list of parameters to see if you need to listen to all of them.
I would take a look at the pageNo. It looks like it might be changing from default value to 2 since you have 2 useEffects probably firing for the same render.

Infinite loop on componentdidupdate with useEffect

I'm using redux and trying to fetch data when my component did update.
I'm using useEffect hook to track posts update and getting the state with useSelector.
I'm having issues as the component is making infinite fetching requests instead of a single request.
Anyone knows how I can stop it from making infinite requests
and make a single request if posts updated?
my code:
const posts = useSelector((state) => state.posts.posts);
useEffect(() => {
dispatch(getPosts(page));
}, [posts]);
image showing infinite fetching requests being made
From useEffect documentation
If you’re familiar with React class lifecycle methods, you can think of useEffect Hook as componentDidMount, componentDidUpdate, and componentWillUnmount combined.
So, dispatch(getPosts(page)) will be called on component mount as well when any of the dependency provided get changed, this will make an API request and fetch the posts of this page. Which will eventually update the state.posts.posts once the API is successful. As, the same state.posts.posts is given as dependency to the useEffect hook this will trigger the function to get executed again and the cycle goes on.
For example if you want to make the API call and fetch new posts when there's a change in the page you should provide page as dependency instead of posts as shown below
const posts = useSelector((state) => state.posts.posts);
useEffect(() => {
dispatch(getPosts(page));
}, [page]);
const posts = useSelector((state) => state.posts.posts);
useEffect(() => {
dispatch(getPosts(page));
}, []);
const updateNeeded = useSelector((state) => state.posts.updateNeeded);
useEffect(() => {
if (updateNeeded) {
dispatch(getPosts(page));
}
}, [updateNeeded]);
Change updateNeeded to true by a dispatch action when you want to fetch a new update, and when the update is fetched dispatch an action which will make this flag to false again.

Next js routing triggers useEffect

I'm trying to fetch data inside useEffect using axios but it fetches the data everytime I change the page. Is there a way to not trigger useEffect when changing the page? I tried to use shawllow push but it didn't work. I can't fetch on server side because I use next/router inside axios interceptor.
import { useRouter } from 'next/router';
const router = useRouter();
router.push('/', '/', { shallow: true })
With the above code, it will trigger useEffect when switching routes.
useEffect(() => {
fetch.get('/endpoint').then(response => {
// do stuff
});
}, []);
If you have something in useEffect that you only want to run once, add an empty array as the dependency array.
Example:
useEffect(() => {
// your axios fetch here
}, []);
Empty array as the dependencies means the effect is run once. If you don't specify the dependencies, the effect will run after every render.
Try:
useEffect(() => {
fetch.get('/endpoint').then(response => {
// do stuff
});
}, []); // the empty array will call useEffect only for first time while loading the component
Refer: https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects See Notes
Shallow-routing only works for same page. See this.
If you stick to shallow-routing, you have to aggregate the pages into one page with dynamic-routes.
So I think it'd be better to use some cache strategy within useEffect.

Resources