Optimistic UI

Apollo provides the great feature of being able to update the UI in an optimistic manner. An optimistic manner means that Apollo adds the new data or post to the storage before the request has finished. The advantage is that the user can see the new result, instead of waiting for the response of the server. This solution makes the application feel faster and more responsive.

This section expects the update function of the Mutation component to already be implemented. Otherwise, this UI feature will not work. We need to add the optimisticResponse property to our mutation, as follows:

optimisticResponse= {{
__typename: "mutation",
addPost: {
__typename: "Post",
text: postContent,
id: -1,
user: {
__typename: "User",
username: "Loading...",
avatar: "/public/loading.gif"
}
}
}}

The optimisticResponse can be anything from a function to a simple object. The return value, however, needs to be a GraphQL response object. What you see here is an addPost object that looks like our GraphQL API could return it, if our request is successful. You need to fill in the __typename fields, according to the GraphQL schema that you are using. That is why the type names Post and User are inside of this fake object.

The id of the optimistic response is set to minus one. React expects that every component in a loop gets a unique key. We usually use the id of a post as the key. Minus one is never used by any other post, because MySQL starts counting at one. Another advantage is that we can use this id to set a special class to the post item in our list.

Furthermore, the username and the user's avatar are set to loading. That is because we don't have built-in authentication. React and Apollo do not have a user associated with the current session, so we cannot enter the user's data into the optimisticResponse. We fix this once the authentication is ready. This is an excellent example of how to handle a situation in which you do not have all of the data until you receive a response from the server.

To set a particular class on the list item, we conditionally set the correct className in our map loop. Insert the following code into the render method:

{posts.map((post, i) => 
<div key={post.id} className={'post ' + (post.id < 0 ? 'optimistic': '')}>
<div className="header">
<img src={post.user.avatar} />
<h2>{post.user.username}</h2>
</div>
<p className="content">
{post.text}
</p>
</div>
)}

An example CSS style for this might look as follows:

.optimistic {
-webkit-animation: scale-up 0.4s cubic-bezier(0.390, 0.575, 0.565, 1.000) both;
animation: scale-up 0.4s cubic-bezier(0.390, 0.575, 0.565, 1.000) both;
}

@-webkit-keyframes scale-up {
0% {
-webkit-transform: scale(0.5);
transform: scale(0.5);
}
100% {
-webkit-transform: scale(1);
transform: scale(1);
}
}

@keyframes scale-up {
0% {
-webkit-transform: scale(0.5);
transform: scale(0.5);
}
100% {
-webkit-transform: scale(1);
transform: scale(1);
}
}

CSS animations make your applications more modern and flexible. If you experience issues when viewing these in your browser, you may need to check whether your browser supports them.

You can see the result in the following screenshot:

The loading spinner and the username are removed once the response arrives from our API, and the update function is executed again with the real data. You do not need to take care of removing the loading post yourself; it is done by Apollo automatically. Any spinner component from an npm package or GIF file can be used where I have inserted the loading animation. The file that I am using needs to be saved under the public folder, with the name loading.gif, so that it can be used through the CSS that we added in the preceding code.

Everything is now set up for sending new posts. The user interface responds immediately, and shows you the new post.

However, what about new posts from your friends and colleagues? Currently, you need to reload the page to see them, which is not very intuitive. At the moment, we only add the posts that we send on our own, but do not receive any information about new posts from other people. I will show you the quickest way to handle this in the following section.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.51.117