Refactor Inlined React setState Function to a setState Updater Factory

Erik Aybar
InstructorErik Aybar
Share this video with your friends

Social Share Links

Send Tweet
Published 7 years ago
Updated 6 years ago

React's setState accepts an updater function that given current state returns new state. To better define and manage our setState usages, we can extract our inlined setState function to a setState updater factory. This enables us to give it a descriptive name, define required arguments, and ease future reuse, refactoring and composition for updating component state in our application.

Instructor: [00:03] Instead of inlining this whole setState function here, what we can do is, we're going to write a function here. This is going to be our setState updater function. We will give it a descriptive name, which is going to be, "set tweet liked." It's going to need to know the tweet ID and also the new liked.

[00:23] Shall we be transitioning to liked or transitioning to unliked? This is going to return, essentially, what we had here. Now, rather than looking up the current state of it, we will just transition to using the new liked. We'll assume that when we invoke this, we know what we want. We'll update this usages of is liked to new liked.

[00:50] We'll be flipping that logic around, since we're assuming that the consumer of this is going to handle the toggling logic. Now to plug this in, we can invoke it here, "set tweet liked." The arguments that it requires is tweet ID and the new liked, which is going to be the opposite of the current liked, which we know we can look up by currying includes on our liked tweets.

[01:18] Now when we click this, we can see that the number is updating as well as the heart is updating appropriately. We have yet to handle the failure case.

bcyn
bcyn
~ 6 years ago

Why did you have to negate isLiked/newLiked? Seems to me it's just more confusing and doesn't functionally change anything, maybe I missed something.

Erik Aybar
Erik Aybarinstructor
~ 6 years ago

Why did you have to negate isLiked/newLiked? Seems to me it's just more confusing and doesn't functionally change anything, maybe I missed something.

bcyn, the reason for negating newLiked was that by extracting into setTweetLiked(tweetId, newLiked) we moved away from "looking up a tweet's currently liked status (isLiked) within the setState function and toggling it" to now "invoking setTweetLiked with the desired liked status (newLiked) as a setter". isLiked as it was previously would be the opposite of newLiked.

So rather than saying "toggle the tweet's liked status", we can explicitly say "like the tweet" or "unlike the tweet". I preferred the setter to reduce ambiguity for setting/reverting state asynchronously that we might run into if we left this as a toggle based on current state at the time of setState invocation.

In retrospect it would have been more clear to rearrange the ternary such as shouldLike ? whenShouldLike : whenNotShouldLike rather than negating the condition as I did as !shouldLike ? whenNotShouldLike : whenShouldLike

I hope that helps clear things up. Good question really 😃

Markdown supported.
Become a member to join the discussionEnroll Today