Home > other >  How to rerender react component automatically upon deleting an item?
How to rerender react component automatically upon deleting an item?

Time:05-16

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;
  • Related