skip to Main Content
const fetchAllNotes = async () => {
    try {
      console.log("Fetching notes...");
      const response = await fetch(`${host}/notes/fetchAllNotes`, {
        method: "GET",
        headers: {
          "Content-type": "application/json",
          "jwt-token": tkn,
        },
      });
      const json = await response.json();
      console.log(json);
      return (json);

    } catch (error) {
      console.log("Error fetching notes:", error);
      return ([]);
    }
  };

— Above is my function to fetch all notes using api.

//Component I am rendering

import { useContext, useEffect, useState } from "react";
import noteContext from "./noteContext";
import {Container} from 'react-bootstrap'
import Noteitem from "./Noteitem";
import AddNote from "./AddNote";

export default function Notes(){
    const {fetchAllNotes} = useContext(noteContext);
    
    const [notes, setNotes] = useState([]);
    

    useEffect(() => {
        async function getNotes(){
            console.log("Use Effect HOOK...");
         const data = await fetchAllNotes();
          setNotes(data);
        }
        getNotes();
      }, []);


    return(<>
    <AddNote />
    <Container>
        <h2>Your Notes: </h2>
        <Container className="row my-2">
        {notes.map(note =>{
            return <Noteitem key={note._id} note={note} />;
        })}
        </Container>
        
    </Container>

    </>)
}

— The problem is it updates the UI on initial render, but if i update or delete a note it won’t show up until I refresh the page. If i put the notes(state variable) as dependency in Use effect it starts an infinite loop. I am so struck for last 2 days trying to solve it. Any help is much appreciated / Thank You 😀

async function getNotes(){
            console.log("Use Effect HOOK...");
         const data = await fetchAllNotes();
          setNotes(data);
        }

useEffect(() => {
        getNotes();
      }, [notes]); 

— i tried doing something like this but then it just starts infinite loop

3

Answers


  1. When you perform a CRUD operation, just refresh the data at the bottom of the function.

    e.g.

    const { fetchAllNotes } = useContext(noteContext);
    
    const [notes, setNotes] = useState([]);
    
    const getNotes = async () => {
      const data = await fetchAllNotes();
      setNotes(data);
    };
    
    // Initial render
    useEffect(() => {
      getNotes();
    }, []);
    
    const deleteRecord = async () => {
      await deleteRecord();
      await getNotes(); // Refresh here
    };
    
    Login or Signup to reply.
  2. If you put notes in the dependencies array of the useEffect, the callback of useEffect will be executed everytime notes is updated (so when setNoted is called). That’s why you have an infinite loop.

    If you want to update your data everytime an action is done, the best way is to separate the function getNotes like you did, calling it when the component is initialised (with useEffect with an empty dependency array) and every time an operation is done

    Like this :

    const updateNote = async (id, note) => {
       await yourMethodToUpdateTheNote(id, note);
       getNote();
    }
    
    Login or Signup to reply.
  3. The problem is this code:

      useEffect(() => {
        getNotes();
      }, [notes]); 
    

    You have getNotes that depends on notes, which is a recursive dependency, just remove the notes from the effect:

      useEffect(() => {
        getNotes();
      }, []); 
    

    But to fix your problem I suggest putting your setState into the context and when you call update or delete you fetch new Data and call setState with the results. You also don’t need to expose fetchNotes only expose the function that will fetch and set the state.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search