英文:
Infinite Loop when trying to keep data UpToDate
问题
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 ([]);
}
};
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>
</>)
}
async function getNotes(){
console.log("Use Effect HOOK...");
const data = await fetchAllNotes();
setNotes(data);
}
useEffect(() => {
getNotes();
}, [notes]);
The code has been translated.
英文:
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
答案1
得分: 0
当您执行CRUD操作时,只需在函数底部刷新数据。
例如:
const { fetchAllNotes } = useContext(noteContext);
const [notes, setNotes] = useState([]);
const getNotes = async () => {
const data = await fetchAllNotes();
setNotes(data);
};
// 初始渲染
useEffect(() => {
getNotes();
}, []);
const deleteRecord = async () => {
await deleteRecord();
await getNotes(); // 在这里刷新
};
英文:
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
};
答案2
得分: 0
如果你将 notes
放在 useEffect
的依赖数组中,那么每次 notes
被更新时(也就是当调用 setNotes
时),useEffect
的回调函数就会被执行。这就是为什么会出现无限循环的情况。
如果你想在每次操作完成后更新你的数据,最好的方式是将 getNotes
函数分离出来,像你所做的那样,在组件初始化时调用它(使用一个空的依赖数组来配合 useEffect
),以及在每次操作完成后调用它。
就像这样:
const updateNote = async (id, note) => {
await yourMethodToUpdateTheNote(id, note);
getNotes();
}
英文:
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();
}
答案3
得分: 0
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.
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论