【问题标题】:React axios get request without resulting in infinite loop using useEffect使用 useEffect 反应 axios 获取请求而不会导致无限循环
【发布时间】: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;

【问题讨论】:

    标签: reactjs mongodb axios react-hooks use-effect


    【解决方案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 的建议做了,它最终工作了
    猜你喜欢
    • 2021-04-10
    • 2021-11-03
    • 2020-10-27
    • 2020-03-05
    • 2020-08-27
    • 2020-11-16
    相关资源
    最近更新 更多