Optimistic UI updates come with challenges that can vary for every use case. In our scenario of “liking a tweet”, one challenge that we face is preventing doubly updating and reverting state in the event of the user clicking “like” in rapid succession. In the case of a request failure our current solution results in the false impression that the tweet was successfully liked.
One solution that fits our use case is to simply raise and lower a boolean flag to indicate whether a like tweet request is pending or not and short circuit our onClickLike
method to "do nothing" if a request is already pending. Since we don’t require this information in our render method or on component state, we can simplify this further by making use of a class instance property to store this value.
Hi! As I see the flag "likeRequestPending" don't allow to make parallels optimistic updates, because we will wait until a first request will complete or failure. Am I right?
Hi Andrey, good catch and question! You're right that as-is likeRequestPending
doesn't account for multiple/parallel requests.
If that did become a requirement, the current solution could be modified to support that. One solution is to change likeRequestPending
from a boolean into an array of ids such as pendingTweetRequests
to track pending requests for individual tweets by id. Example:
class App extends React.Component {
// An array of tweet ids representing pending requests
pendingTweetRequests = [];
onClickLike = tweetId => {
// 1) Is a request already pending for this tweet?
if (this.pendingTweetRequests.includes(tweetId)) {
return;
}
// ...
// 2) Add this tweet to pendingTweetRequests
this.pendingTweetRequests = this.pendingTweetRequests.concat(tweetId);
likeTweetRequest(tweetId, !isLiked)
// ...
.then(() => {
// 3) Remove tweet from pendingTweetRequests
this.pendingTweetRequests = this.pendingTweetRequests
.filter(id => id !== tweetId);
});
};
// ...
}
Scenario:
Is this understanding correct ? If yes, is there an easy way to not let this happen?