使用 useEffect 反应 axios 获取请求而不会导致无限循环
Posted
技术标签:
【中文标题】使用 useEffect 反应 axios 获取请求而不会导致无限循环【英文标题】:React axios get request without resulting in infinite loop using useEffect 【发布时间】:2020-10-18 03:24:38 【问题描述】:我通过这个 axios get 请求得到一个无限循环,但是当我尝试在 useEffect 结束时将消息或 setMessages 作为 [] 内的值时,需要单击 2 次按钮来更新屏幕或它导致错误提示网络资源不足。那我应该放什么呢?
function CommentsPage()
const user = useAuth0();
const [query, setQuery] = useState("");
const [messages, setMessages] = useState([]);
//fetches data from mongodb for comments
useEffect(() =>
fetchComments();
, [messages]);
//calls backend to fetch data from the messages collection on mongodb
async function fetchComments()
const response = await axios.get("http://localhost:5000/messages");
setMessages(response.data);
// handles when a user types in the comment bar
function handleOnInputChange(event)
// current value of what user is typing
const value = event.target;
setQuery(value);
// handles when a user posts a comment
function postComment(comment, user)
const newMessage =
username: user.name,
content: comment,
;
// calls backend to send a post request to insert a new document into the collection
axios
.post("http://localhost:5000/messages", newMessage)
.then((res) => console.log(res.data));
setQuery("");
fetchComments();
// handles when a user deletes a comment
function deleteComment(id)
axios
.delete("http://localhost:5000/messages/delete/" + id)
.then((res) => console.log(res.data));
fetchComments();
setMessages(messages.filter((message) => message.id !== id));
// handles when a user updates a comment
function updateComment(id)
// calls a pop up that allows user to input their new comment
const editedContent = prompt("please enter new message");
const newMessage =
username: user.name,
content: editedContent,
;
axios
.put("http://localhost:5000/messages/update/" + id, newMessage)
.then((res) => console.log(res.data));
fetchComments();
console.log(messages);
return (
<Container>
<CommentsContainer>
messages.length ? (
messages.map((message) =>
/* if the usernames match then a user comment is returned
otherwise an other comment will be returned */
return message.username === user.name ? (
<UserComment
key=message._id
username=message.username
content=message.content
deleteComment=deleteComment
id=message._id
updateComment=updateComment
/>
) : (
<OtherComment
key=message._id
username=message.username
content=message.content
/>
);
)
) : (
<div>There are no comments. Make one!</div>
)
</CommentsContainer>
<CommentBarStyle htmlFor="search-input">
<input
name="commentBar"
type="text"
value=query
id="search-input"
placeholder="Write a comment..."
onChange=handleOnInputChange
/>
<AddIcon
className="fas fa-plus"
onClick=() => postComment(query, user)
/>
</CommentBarStyle>
</Container>
);
export default CommentsPage;
【问题讨论】:
【参考方案1】:您的 useEffect 将在每次消息状态发生变化时运行。像这样改变你的 useEffect:
useEffect(() =>
fetchComments();
,[null]);
【讨论】:
对不起,也许我应该更具体一些,如果我将空数组传递给 useEffect,那么每当我尝试制作、编辑或删除评论时,我都需要进入另一个页面在它更新之前,当我希望它在那里更新时。那么我怎样才能像这样更新页面呢? 只需将 fetchComments() 放入您所有的 axios 中即可。然后回调它会解决您的问题。 ` axios.post('url').then(()=> fetchComments() ) `【参考方案2】:您正在更新 fetchComments 中的“消息”状态...所以每次更新此状态时都会调用您的 useEffect,因为它具有消息作为依赖项。
useEffect(() =>
fetchComments();
, [messages]);
//calls backend to fetch data from the messages collection on mongodb
async function fetchComments()
const response = await axios.get("http://localhost:5000/messages");
setMessages(response.data);
试试这个:
useEffect(() =>
fetchComments();
, []);
如果您这样做,您的组件将在挂载阶段调用 fetchComments,而不是在每次消息状态更改时调用它。
【讨论】:
对不起,也许我应该更具体一些,如果我将空数组传递给 useEffect,那么每当我尝试制作、编辑或删除评论时,我都需要进入另一个页面在它更新之前,当我希望它在那里更新时。那么我怎样才能像这样更新页面呢? 你能把你的代码放在一个沙箱里吗? 感谢您查看它的建议,但我按照 Adeel 的建议做了,它最终工作了以上是关于使用 useEffect 反应 axios 获取请求而不会导致无限循环的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的 axios 使用 React.useEffect 一遍又一遍地从 Rails 后端获取调用?
在 useEffect 挂钩中使用 axios 取消令牌时如何修复失败的测试
使用 axios 获取数据后 React useEffect 返回空数组