Avoid multiple useEffect on component on component load

Viewed 2644

I building a simple like, bookmark functionality in my react app.

const [liked, setLiked] = useState();
const [bookmarked, setBookmarked] = useState();

  useEffect(() => {
    post.liked ?  setLiked(true):  setLiked(false);
    post.bookmarked ?  setBookmarked(true) : setBookmarked(false);
  }, []);

  useEffect(() => {
    axios.post(`${baseURL}/content/like`).then((res) => console.log(res));
  }, [liked]);

Whenever the component gets loaded it useEffect runs twice

How can I avoid intial axios post and axios post only if the state changes?

I want to send a post request whenever the liked State changes.

3 Answers

You cannot avoid the useEffect hook from executing multiple times. The function will be called every time the liked value changes, however, you can check the liked value before calling axios.post to prevent making a request on the initialization state of the liked state:

const [liked, setLiked] = state(false);
...
useEffect(() => {
  if (liked) {
    axios.post(`${baseURL}/content/like`).then(res => console.log(res));
  }
}, [liked]);

Assuming post.liked is the current value in the backend, and you call setLiked on a button click or something as well, I would just compare if the state value is different from that current backend value:

const [liked, setLiked] = useState(post.liked);

useEffect(() => {
    if (liked !== post.liked) {
        axios.post(`${baseURL}/content/like`).then((res) => console.log(res));
    }
}, [liked, post.liked]);
  const [liked, setLiked] = useState(false);
  const [bookmarked, setBookmarked] = useState(false);

  const handleLike = (likeStaus) => {
    setLiked(likeStaus);
    axios.post(`${baseURL}content/like`).then((res) => console.log(res));
  };
  const handleBookmark = (bookmarkStatus) => {
    setBookmarked(bookmarkStatus);
    axios.post(`${baseURL}content/bookmark`).then((res) => console.log(res));
  };

<button
          className={
            liked
              ? "meta-button btn btn-default text-danger btn-sm"
              : "meta-button btn btn-default btn-sm"
          }
          onClick={() => handleLike(!liked)}
        >
          <i className="lar la-heart"></i>
        </button>

I ended up using a separate function to handle like and bookmark Since my post.liked is an array of users, I need inital useEffect [] to check of user in array

Related