Working with a simple card component, to which I load data from an API with Axios get by using UseEffect. The purpose is that when the component is loaded, it loads the data to it once.
The issue is that data is not loaded correctly on load but repeatedly after it when the component updates. How can I make it so that it loads the data once when the page is loaded but not after that?
I have omitted the API url but it is tested and returns data correctly from backend.
Card component:
import React from 'react';
import { Card, CardImg, CardBody, CardTitle, CardSubtitle, Container, Row, Col } from 'reactstrap';
import { useEffect, useState } from "react";
import { APIGet } from '../API.js';
function RenderCardLoadMore() {
const [data, setData] = useState([]);
const resource = 'search';
const params = { 'limit': '2' };
const results = APIGet(resource, params);
useEffect(() => {
console.log("initialload");
setData(results);
}, []);
return (
<Container fluid>
<Container>
<Row>
{data.map((v, i) => (
<Col className="py-2" key={i} xs={12} md={4} lg={3}>
<Card className="explore_event_card shadow">
<CardBody>
<CardTitle className="card_header">{v.Title}</CardTitle>
<CardSubtitle>{v.SubTitle}</CardSubtitle>
</CardBody>
</Card>
</Col>
))}
</Row>
</Container>
</Container>
);
}
export default RenderCardLoadMore;
API component:
import { useEffect, useState } from 'react';
import axios from 'axios';
const API_URL = 'https://myapi/'; /*url omitted for this question, tested and working*/
const session_id = localStorage.getItem("session_id");
export function APIGet (resource, params) {
const [data, setData] = useState([]);
const url = API_URL + resource;
params['session_id'] = session_id;
useEffect(() => {
axios.get(url, {params: params}).then((v) => {
setData(v.data)
}).catch( (err) => console.log(["APIGet error:", err]) )
}, [url]); //url as 2nd argument not needed?
return data;
}
You could remove url
and use an empty dependency array so the useEffect
hook is triggered only once after the initial render. From what I can tell though, APIGet
doesn't need to be a hook and doesn't need to use the useState
hook. I can simply return the Promise chain returned from axios.
API
import axios from 'axios';
const API_URL = 'https://myapi/.....';
export function APIGet (resource = "", params = {}) {
const session_id = JSON.parse(localStorage.getItem("session_id"));
const url = API_URL + resource;
params['session_id'] = session_id;
return axios.get(url, {params: params})
.then((v) => {
return v.data
})
.catch((err) => console.log(["APIGet error:", err]));
}
RenderCardLoadMore - Call APIGet
in the useEffect
hook and update the state when Promise resolves.
import { APIGet } from '../API.js';
function RenderCardLoadMore() {
const [data, setData] = useState([]);
const resource = 'search';
const params = { 'limit': '2' };
useEffect(() => {
console.log("initialload");
APIGet(resource, params)
.then(results => {
setData(results);
});
}, []);
return (....);
}