How to call mutate only once on page visit? (For Change Email Confirmation Links)
I'm struggling to get a mutation to fire exactly once in my application. Here's the scenario: when a user decides to reset their email, a token with a random UUID is generated and stored in our database. The new email then receives a confirmation link like
base-url.com/email-reset?token={token_uuid}
. The user clicks the link and lands on a page that shows a modal, which varies based on whether it's loading, successful, or encounters an error.
My goal is to trigger the resetEmail
mutation only once, as soon as the token from the URL becomes available. However, I've noticed that the mutation often gets triggered multiple times. This is an issue because the first successful mutation deletes the token from the backend, causing any subsequent mutations to fail and display the error modal although the email change is successful.
Here's a code snippet for context:
I've tried using useState
to set a resetEmailTried
flag, but that hasn't solved the problem. I suspect this is because React's state doesn't update instantly. Any help or insights would be much appreciated 🙏5 Replies
use a react ref that is initially false and set it to true inside your use effect after you send the query
and then add a check for it being false to your if statement
happy path is just for readability, and a pattern ive grown to love and highly reccomend
since hasSent is a ref, we dont need to put it in the dep array
Thanks for the quick reply! I'll give that a try. And I did a quick search on happy path "pattern" (hard to call it pattern, more like code style, right?). Looks super intriguing and logical, you might have convinced me
Is definitely related to not trying to nest code too much which I read about some time ago and have naturally tried to implement for a longer than that https://medium.com/codex/why-you-shouldnt-nest-your-code-185cf2e2cde3
Doesn't work unfortunately. Here's my code:
if I add a console.log(emailResetSent.current); directly above the mutate I still can see two mutations happening and false being printed twice
that would be because your probably in react strict mode which fully mounts and unmounts your component twice during development to make sure that your hooks are properly made
try running in production mode, or turn off strict mode and you should see it work
Ok, I think I caught the issue. I have a Layout which contains a sidebar that fetches and displays data. Apparently this causes my component to render twice.
If I comment out the sidebar the issue disappears.
Thanks for the help, I really appreciate that!