Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

Sorry, you do not have permission to ask a question, You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please type your username.

Please type your E-Mail.

Please choose an appropriate title for the post.

Please choose the appropriate section so your post can be easily searched.

Please choose suitable Keywords Ex: post, video.

Browse

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Navigation

  • Home
  • About Us
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • About Us
  • Contact Us
Home/ Questions/Q 8910

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Latest Questions

Author
  • 60k
Author
Asked: November 28, 20242024-11-28T05:30:09+00:00 2024-11-28T05:30:09+00:00

Consider if you can replace useEffect with event handler (We Might Not Need an Effect #2)

  • 60k

What this article series are about πŸ”

This article series are basically a summary of You Might Not Need an Effect, which is a React official documentation about the usage of useEffect hook in React.

The original article is really really good, for sure better than my summary. So, if you have time, I highly recommend you to read the original article.

My motivation is just to provide a quick summary both for myself and for others who might be busy or a bit lazy to read through the whole article.

Yeah, it's for you πŸ˜‰ haha

This is the second article of the series. And the key takeaway is really simple.

Always consider if you can do it inside of event handler πŸ’‘

All of the example covered in this article are about how we can avoid using useEffect by moving the logic to the event handler.

I'm not covering Passing a data to the parent,
because it's rather about the flow of data in React.

Before diving into them, let's briefly make it clear why we need to reduce useEffect in the first place.

Why we need to reduce useEffect in the first place?

  • Re-render happens after each setState function in each of useEffect
  • Complexity. It's hard to understand the flow of the code if we have too many useEffect

So, let's see how we can avoid using useEffect by moving the logic to the event handler or just during rendering.

Example 1, Bad πŸ‘Ž

When we want to do some shared logic between multiple event handler function, we might be tempted to put the logic inside useEffect.
But we actually shoudn't do that.

// Let's assume this function is defined elsewhere const addToCart = (product) => {   product.isInCart = true; };  function ProductPage({ product, addToCart }) {   // πŸ”΄ Avoid: Event-specific logic inside an Effect   useEffect(() => {     if (product.isInCart) {       showNotification(`Added ${product.name} to the shopping cart!`);     }   }, [product]);    function handleBuyClick() {     addToCart(product);   }    function handleCheckoutClick() {     addToCart(product);     navigateTo('/checkout');   }   // ... } 
Enter fullscreen mode Exit fullscreen mode

Example 1, Good πŸ‘

If you want to create some shared logic between event handlers, just create a function.

function ProductPage({ product, addToCart }) {   // βœ… Good: Event-specific logic is called from event handlers   function buyProduct() {     addToCart(product);     showNotification(`Added ${product.name} to the shopping cart!`);   }    function handleBuyClick() {     buyProduct();   }    function handleCheckoutClick() {     buyProduct();     navigateTo('/checkout');   } } 
Enter fullscreen mode Exit fullscreen mode

Example 2, Bad πŸ‘Ž

Again, if you can do it on event handler, just do it there rather than using useEffect.

function Form() {   const [firstName, setFirstName] = useState('');   const [lastName, setLastName] = useState('');    // βœ… Good: This logic should run because the component was displayed, not because of an event   useEffect(() => {     post('/analytics/event', { eventName: 'visit_form' });   }, []);    // πŸ”΄ Avoid: Event-specific logic inside an Effect. You don't need a state and useEffect for that.   const [jsonToSubmit, setJsonToSubmit] = useState(null);   useEffect(() => {     if (jsonToSubmit !== null) {       post('/api/register', jsonToSubmit);     }   }, [jsonToSubmit]);    function handleSubmit(e) {     e.preventDefault();     setJsonToSubmit({ firstName, lastName });   }   // ... } 
Enter fullscreen mode Exit fullscreen mode

Example 2, Good πŸ‘

function Form() {   const [firstName, setFirstName] = useState('');   const [lastName, setLastName] = useState('');    // βœ… Good: This logic should run because the component was displayed, not because of an event   useEffect(() => {     post('/analytics/event', { eventName: 'visit_form' });   }, []);    function handleSubmit(e) {     e.preventDefault();     // βœ… Good: Event-specific logic is in the event handler     post('/api/register', { firstName, lastName });   }   // ... } 
Enter fullscreen mode Exit fullscreen mode

Example 3, Bad πŸ‘Ž

It looks like we're using useEffect to chain multiple state update each other.

function Game() {   const [card, setCard] = useState(null);   const [goldCardCount, setGoldCardCount] = useState(0);   const [round, setRound] = useState(1);   const [isGameOver, setIsGameOver] = useState(false);    useEffect(() => {     if (card !== null && card.gold) {       setGoldCardCount((c) => c + 1);     }   }, [card]);    useEffect(() => {     if (goldCardCount > 3) {       setRound((r) => r + 1);       setGoldCardCount(0);     }   }, [goldCardCount]);    useEffect(() => {     if (round > 5) {       setIsGameOver(true);     }   }, [round]);    useEffect(() => {     alert('Good game!');   }, [isGameOver]);    function handlePlaceCard(nextCard) {     if (isGameOver) {       throw Error('Game already ended.');     } else {       setCard(nextCard);     }   } } 
Enter fullscreen mode Exit fullscreen mode

Example 3, Good πŸ‘ (After we remove all unnecessary useEffect)

Let's see how we can remove unnecessary useEffect.

function Game() {   const [card, setCard] = useState(null);   const [goldCardCount, setGoldCardCount] = useState(0);   const [round, setRound] = useState(1);   // const [isGameOver, setIsGameOver] = useState(false); // We don't need this state   // Instead, βœ… calculate what you can during rendering   const isGameOver = round > 5;    function handlePlaceCard(nextCard) {     if (isGameOver) {       throw Error('Game already ended.');     }      // βœ… Calculate all the next state in the event handler, rather than in useEffect     setCard(nextCard);     if (nextCard.gold) {       if (goldCardCount <= 3) {         setGoldCardCount(goldCardCount + 1);       } else {         setGoldCardCount(0);         setRound(round + 1);         if (round === 5) {           alert('Good game!');         }       }     }   } } 
Enter fullscreen mode Exit fullscreen mode

Takeaway

(Almost) Never use useEffect for event-specific logic. Just call the logic directly from the event handler function.

I actually couldn't come up with any case where we have to use useEffect for event-specific logic, please tell me if you can think of any cases.

Reference

  • Sharing logic between event handlers
  • Sending a POST request
  • Chains of computations

See you again in #3!

javascriptreactuseeffectwebdev
  • 0 0 Answers
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

Sidebar

Ask A Question

Stats

  • Questions 4k
  • Answers 0
  • Best Answers 0
  • Users 2k
  • Popular
  • Answers
  • Author

    How to ensure that all the routes on my Symfony ...

    • 0 Answers
  • Author

    Insights into Forms in Flask

    • 0 Answers
  • Author

    Kick Start Your Next Project With Holo Theme

    • 0 Answers

Top Members

Samantha Carter

Samantha Carter

  • 0 Questions
  • 20 Points
Begginer
Ella Lewis

Ella Lewis

  • 0 Questions
  • 20 Points
Begginer
Isaac Anderson

Isaac Anderson

  • 0 Questions
  • 20 Points
Begginer

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help

Footer

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore, ask, and connect. Join our vibrant Q&A community today!

About Us

  • About Us
  • Contact Us
  • All Users

Legal Stuff

  • Terms of Use
  • Privacy Policy
  • Cookie Policy

Help

  • Knowledge Base
  • Support

Follow

© 2022 Querify Question. All Rights Reserved

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.