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;
CodePudding user response:
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;
CodePudding user response:
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;
}));
});
};
CodePudding user response:
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;