Reputation: 151
I would like to ask why my component is not rerendering after my state is changed and I need to refresh it (switch between routes) to see changes. Well, the interesting fact is that the first time when I click the delete button page (component) does not rerender but after I switch routes and come back the item is deleted and when I try to delete other items, it gets deleted instantly not like the first time.
This is my code:
import React, {useEffect, useState} from 'react';
import ApiFactory from '../mock';
import Editor from '../Editor';
import ProductCard from '../components/product-card/product-card';
import ProductEdit from '../components/product-edit/product-edit';
export default function Admin() {
const [items, setItems]= useState([]);
useEffect(() => {
getProducts();
}, [items]);
function getProducts() {
ApiFactory.getInstance().get('/api/products')
.then((res) => {
if(res.status == 200) {
setItems(res.data);
}
})
.catch((error) => { console.log(error)})
}
function handleDelete (productId) {
ApiFactory.getInstance().delete(`/api/products/${productId}`)
.then(()=> getProducts()
);
}
return (
<>
{
items.map((item, index) => {
console.log(item.id)
return <>
<div key={index}>
<ProductCard product={item}></ProductCard>
<button onClick={() => handleDelete(item.id)}>Delete</button>
</div>
</>
})
}
</>
);
}
I am quite new in React can anybody explain why it happens and how can I fix it?
Upvotes: 1
Views: 92
Reputation: 237
I believe it's because of how you have useEffect set up.
change the useEffect to only make the GET API call once (on initial load):
useEffect(() => {
getProducts();
}, []); // remove the dependency here. You may have made an infinite loop here.
const getProducts = () => {
ApiFactory.getInstance().get('/api/products')
.then((res) => {
if(res.status == 200) {
setItems(res.data);
}
})
.catch((error) => { console.log(error)})
}
If you confirmed that the API call is handling your errors / successes (are you getting non 200 status codes ? those may not be handled)
Add error catching to handleDelete to make sure this call works.
const handleDelete = (productId) => {
ApiFactory.getInstance().delete(`/api/products/${productId}`)
.then(getProducts())
).catch((error) => { console.log(error)})
}
You may additionally do as another user suggested and move even more logic away from the API calls (not required though) to have state locally and not re-fetch data from the API.
Upvotes: 1