'How to rerender react component automatically upon deleting an item?
I am trying to implement a delete functionality in my app, but when I click on the delete button, the item does get deleted but the page is not rerendered right away. I still have to manually refresh the page to see the updated list of items. Is there a way to automatically rerender the page as soon as I hit the delete button? Here is my code:
import React, {useState, useEffect, useRef} from 'react';
import Header from './Header';
import Footer from './Footer';
import Note from './Note';
import CreateArea from './CreateArea';
import axios from 'axios';
function App() {
const [notes, setNotes] = useState([]);
useEffect(() => {
axios.get('http://localhost:4000/').then((response) => {
setNotes(response.data);
});
console.log(notes);
}, []);
const deleteItem = (id) => {
axios
.delete('http://localhost:4000/delete/' + id)
.then(() => {
setNotes((previousValue) => {
return previousValue.filter(({_id}) => {
return _id !== id;
});
});
});
};
return (
<div>
<Header />
<CreateArea />
{notes.map((item, index) => (
<Note
key={item._id}
id={item._id}
noteTitle={item.title}
noteContent={item.content}
onDelete={deleteItem}
/>
))}
<Footer />
</div>
);
}
export default App;
Solution 1:[1]
import React, {useState, useEffect, useRef} from 'react';
import Header from './Header';
import Footer from './Footer';
import Note from './Note';
import CreateArea from './CreateArea';
import axios from 'axios';
function App() {
const [Notes, setNotes] = useState([]);
useEffect(() => {
axios.get('http://localhost:4000/').then((response) => {
setNotes(response.data);
});
console.log(notes);
}, []);
const deleteItem = (id) => {
axios
.delete('http://localhost:4000/delete/' + id)
.then(() => {
setNotes(previousValue.filter(_id =>_id !== id));
});
};
return (
<div>
<Header />
<CreateArea />
{Notes.map((item, index) => (
<Note
key={item._id}
id={item._id}
noteTitle={item.title}
noteContent={item.content}
onDelete={deleteItem}
/>
))}
<Footer />
</div>
);
}
export default App;
Solution 2:[2]
I haven't seen the setter of useState taking a callback before.
Could you try to change your delete handler this way:
const deleteItem = (id) => {
axios
.delete('http://localhost:4000/delete/' + id)
.then(() => {
setNotes(notes.filter(({_id}) => {
return _id !== id;
}));
});
};
Solution 3:[3]
Create forceRender state to count change when the function of deleteItem run complete and resolve, pass forceRender state to dependencies of useEffect, make it fetch again when forceRender state change:
import React, {useState, useEffect, useRef} from 'react';
import Header from './Header';
import Footer from './Footer';
import Note from './Note';
import CreateArea from './CreateArea';
import axios from 'axios';
function App() {
const [notes, setNotes] = useState([]);
const [forceRender, setForceRender] = useState(0); // <=== Create new forceRender state
useEffect(() => {
axios.get('http://localhost:4000/').then((response) => {
setNotes(response.data);
});
console.log(notes);
}, [forceRender]); // <=== pass forceRender state to dependencies
const deleteItem = (id) => {
axios
.delete('http://localhost:4000/delete/' + id)
.then(() => setForceRender(prev => prev + 1)); // <==== set state change if deleteItem() complete
};
return (
<div>
<Header />
<CreateArea />
{notes.map((item, index) => (
<Note
key={item._id}
id={item._id}
noteTitle={item.title}
noteContent={item.content}
onDelete={deleteItem}
/>
))}
<Footer />
</div>
);
}
export default App;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Ingenious_Hans |
| Solution 2 | Igor Loskutov |
| Solution 3 | VMT |
