Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React axios get request without resulting in infinite loop using useEffect

I'm getting an infinite loop with this axios get request, but when I try putting messages or setMessages as the value inside of the [] at the end of useEffect it takes 2 clicks of the button to update the screen or it results in an error saying insufficient network resources. So what should I put instead?

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;
like image 679
Jack Maring Avatar asked Jul 05 '26 13:07

Jack Maring


1 Answers

Your useEffect will run every time when messages state is change. Change your useEffect like this:

useEffect(() => {
    fetchComments();
},[null]);
like image 181
Adeel Avatar answered Jul 07 '26 09:07

Adeel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!