0

I need to pass 2 functions to my useEffect -

  1. one that renders the whole page and sends some general data to the server,
  2. another one is voting function and sends vote results (called "answer") to the server.

I tried to put both functions inside one useEffect, as well as using useEffect twice. Will show code for both of them.

2 useEffects was working for a little bit, then I started getting this error: "Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function".

So, my question is:

  1. Can I call 2 functions under one useEffect or can I have 2 useEffects?
  2. How to get rid of my unmount error? I tried setting isMounted to true/false but still no luck.

Code for both functions in one useEffect:

useEffect(() => {
        let isMounted = true;
        function viewingPoll() {
            fetch(`/api/polls/${pollIview}`)
                .then((resp) => resp.json())
                .then((result) => {
                    if (isMounted) {
                        console.log("my result on pollvoter is", result);
                        if (result.noSuchPoll) {
                            setPoll(false);
                        } else {
                            setPoll(result.pollInfo);
                            console.log("result right here", result); //all the happy points
                        }
                    }
                })
                .catch((err) => {
                    console.log("error in pollvoter.js ", err);
                    this.setState({
                        error: true,
                    });
                });
        }
        viewingPoll();
        function voting() {
            let isMounted = true;
            fetch("/api/vote", {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                },
                body: JSON.stringify({
                    poll_id: poll.id,
                    answer: answer,
                }).then(() => {
                    if (isMounted) {
                        // location.redirect(`/polls/${result.pollId}`);
                        location.reload();
                    }
                }),
            });
        }
        voting();
        return () => {
            isMounted = false;
        };
 }, [answer]);

Example 2: having 2 separate useEffects

 useEffect(() => {
        let isMounted = true;
        function viewingPoll() {
            fetch(`/api/polls/${pollIview}`)
                .then((resp) => resp.json())
                .then((result) => {
                    if (isMounted) {
                        console.log("my result on pollvoter is", result);
                        if (result.noSuchPoll) {
                            setPoll(false);
                        } else {
                            setPoll(result.pollInfo);
                            console.log("result right here", result); //all the happy points
                        }
                    }
                })
                .catch((err) => {
                    console.log("error in pollvoter.js ", err);
                    this.setState({
                        error: true,
                    });
                });
        }
        viewingPoll();
}, [answer]);


useEffect(() => {
        let isMounted = true;
        fetch("/api/vote", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            },
            body: JSON.stringify({
                poll_id: poll.id,
                answer: answer,
            }).then(() => {
                if (isMounted) {
                    // location.redirect(`/polls/${result.pollId}`);
                    location.reload();
                }
            }),
        });
        return () => {
            isMounted = false;
        };
    }, [answer]);
  • See if [this](https://stackoverflow.com/a/63504457/8601641) helps – k33da_the_bug Jul 31 '22 at 14:43
  • What is `location.reload();`? If it's reloading the page it is also reloading the entire app. In other words, the app is unmounted and mounted. Any local state that was enqueued to be processed will be irrelevant as the app starts anew. Using a `isMounted` variable is considered anti-pattern by Dan Abramov (*React maintainer*), and this is why there's no warning for this in React 18. Using a single `useEffect` should be sufficient since they've both the same single dependency on `answer`. – Drew Reese Jul 31 '22 at 21:36
  • Perhaps if you could share a more complete and comprehensive [mcve] so that we can see the bigger picture for what the code is doing we could provide a more optimal solution. – Drew Reese Jul 31 '22 at 21:36

0 Answers0