0

I'm trying to send data to my server after clicking on an image (handleClick function). I have 2 images and I need to know which image got clicked, but I get the correct result sent only after the second click.

I read that useEffect helps this issue, BUT I use useEffect in the same component for another also very crucial function. I tried to squeeze this function inside useEffect as well, but sadly doesn't work (I get "handleClick is not defined" error below on images, where they listen to click event and need to execute handleClick).

Any help will be greately appreciated!

export default function PollVoter() {
    const [poll, setPoll] = useState({});
    const [answer, setAnswer] = useState();

     useEffect(() => {
            function viewingPoll() {
//here goes irrelevant other function info
            } viewingPoll();
//this is relevant:
            const handleClick = (e) => {
                e.preventDefault();
                console.log("e.target", e.target);
                if (e.target.name === "A") {
                    (async () => {
                        setAnswer(1);
                        console.log("I'm clicking on left image");
                        await fetch("/api/vote", {
                            method: "POST",
                            headers: {
                                "Content-Type": "application/json",
                            },
                            body: JSON.stringify({
                                poll_id: poll.id,
                                answer: answer,
                            }),
                        });
                        // .then(() => {
                        //     // location.redirect(`/polls/${result.pollId}`);
                        //     location.reload();
                        //     e.target.value === "";
                        // });
                    })();
                } else if (e.target.name === "B") {
                    (async () => {
                        setAnswer(2);
                        console.log("I'm clicking on right image");
                        await fetch("/api/vote", {
                            method: "POST",
                            headers: {
                                "Content-Type": "application/json",
                            },
                            body: JSON.stringify({
                                poll_id: poll.id,
                                answer: answer,
                            }),
                        });
                    })();
                } else {
                    (async () => {
                        setAnswer(0);
                        console.log("I'm not clicking ");
                        await fetch("/api/vote", {
                            method: "POST",
                            headers: {
                                "Content-Type": "application/json",
                            },
                            body: JSON.stringify({
                                poll_id: poll.id,
                                answer: answer,
                            }),
                        });
                    })();
                }
                // console.log("this is what I answered", answer);
            };
        }, [answer]);

async-await didn't stop my issue either, I did it outside of useEffect.

const handleClick = (e) => {
        e.preventDefault();
        if (e.target.name === "A") {
            (async () => {
                setAnswer(1);
                console.log("I'm clicking on left image");
                await fetch("/api/vote", {
                    method: "POST",
                    headers: {
                        "Content-Type": "application/json",
                    },
                    body: JSON.stringify({
                        poll_id: poll.id,
                        answer: answer,
                    }),
                });
            })();
        } else if (e.target.name === "B") {
            (async () => {
                setAnswer(2);
                console.log("I'm clicking on right image");
                await fetch("/api/vote", {
                    method: "POST",
                    headers: {
                        "Content-Type": "application/json",
                    },
                    body: JSON.stringify({
                        poll_id: poll.id,
                        answer: answer,
                    }),
                });
            })(); ```

UPDATE: Almost fixed an issue, now I'm getting the results twice though. As Drew suggested in the comments, I updated state in my handleClick and fetch in useEffect.

const handleClick = (e) => {
        e.preventDefault();
        console.log("e.target", e.target);
        if (e.target.name === "A") {
            (async () => {
                setAnswer(1);

                console.log("I'm clicking on left image");
            })();

but I added the second useEffect (hope it's allowed, but might be the reason I'm getting my results twice)

 useEffect(() => {
 //this other function stuff
        function viewingPoll() {
            fetch(`/api/polls/${pollIview}`)
//so on
        viewingPoll();
    }, []);

    useEffect(
        (e) => {
            fetch("/api/vote", {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                },
                body: JSON.stringify({
                    poll_id: poll.id,
                    answer: answer,
                }).then(() => {
                    // location.redirect(`/polls/${result.pollId}`);
                    location.reload();
                    e.target.value === "";
                }),
            })();
        },
        [answer]
    );
  • The `handleClick` callback should update the state, then a `useEffect` hook with a dependency on the state should issue the side-effect of making the POST request. The code in both the snippets in your question are trying to use the state value prior to it being processed and updated by React. – Drew Reese Jul 31 '22 at 04:43
  • THANK YOU, it worked! I'm getting useEffect twice now, I'll try to fix it. For some reason I can't comment my code to show you, will update the post. – Ana Ptskialadze Jul 31 '22 at 12:13
  • That may just be a `React.StrictMode` component double-invoking certain methods/hook callbacks to [detect unexpected side-effects](https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects) or double-mounting the app to [ensure reusable state](https://reactjs.org/docs/strict-mode.html#ensuring-reusable-state). I suppose you'll want to check the `answer` state value to ensure it's valid for making the POST request as the `useEffect` is guaranteed to run at least once when the component mounts. – Drew Reese Jul 31 '22 at 20:20

0 Answers0