Conf42 JavaScript 2024 - Online

- premiere 5PM GMT

React and the Art of Gamification

Abstract

Looking to make your React apps more engaging? Learn how to add a playful edge with gamification techniques like scoring systems, badges, and interactive challenges. Let’s level up your user experience, one game element at a time!

Summary

Transcript

This transcript was autogenerated. To make changes, submit a PR.
Hello and warm welcome. I'm Courtney Otto and I'm excited to talk to you today about one of my favorite topics, gamification. Now we're going to see how gamification can transform your react applications into immersive and engaging experiences. Now, when we talk about gamification, it's more than just points and badges. It's really about how we create these applications to make users want to come back for more. Now think about the last app that you couldn't stop using. It had probably gamification elements that you kept, that kept you hooked. Apps like Starbucks, Duolingo, Headspace. These take what might otherwise be routine or even difficult tasks, ordering coffee, learning a new language, or managing anxiety, and really making them a bit more enjoyable by adding in these gamified elements. So whether it's rewards for purchases, progress tracking or daily challenges. These features really do tap into our desire for achievement and keep us coming back. Now, React's component based architecture makes it a natural fit for building these kinds of gamified experiences. It's flexible, it's efficient, and it lets us create reusable, interactive components that elevate user engagement. Now throughout today's session, we're going to explore how you can leverage React to build apps that are not only functional, but are also really fun and truly engaging. And before we jump in, let me introduce myself real quick. I'm Courtney Yato, and I'm currently a developer advocate at Esri, a company that specializes in geographic information systems, or GIS for short. Before joining Esri, I was a high school math and computer science teacher, and I really got to see firsthand how gamification can motivate students in the classroom. For my master's project, I focused on how technology can enhance learning, and I explored how gamified digital experiences can really increase engagement. As a developer advocate, I have been applying some of those gamification principles to the world of development. Particularly in GIS technology. And one of my goals is to help developers understand really how powerful gamification can be, not just in education, but really in all different kinds of applications. So our agenda for today, throughout the next bit, I'm going to take us through five different gamification principles, specifically tailored for react applications. And for each principle, I'll show a real world example of how this has been implemented. So Then to make things interactive, I've prepared a mini workshop, like coding demo, where we're going to build a simple gamified app together. And if you'd like to follow along with that in a bit, you can find the starter code here. Now that we've set the stage for a discussion, let's go ahead and jump into the first principle of gamification. Now this acronym that I came up with, GAMES, The G in the game stands for Gamify Components. These are the core elements that turn ordinary tasks into really engaging experiences. Gamify Components can be anything from experience bars to badges, progress tracking, or even rewards for completing tasks. These elements do create a sense of achievement, motivating users to continue engaging with the app. Now let's look at how this concept comes to life in an app like Codecademy. A Codecademy uses several gamified elements to drive user engagement and motivation. XP points reward users for completing lessons, providing instant feedback, and incentivizing progress. Badges mark milestones, visually representing achievements, while progress bars track advancement through different courses. Additionally, weekly target trackers encourage consistency by setting measurable goals using visual cues to help users stay focused. Now these elements are nicely integrated to enhance the learning experience and maintain user motivation. All right, so next we're going to move on to the letter A, and A stands for Advanced State Management. Now, as apps grow in their complexity, keeping track of state across multiple components really can get a bit tricky. So this is where React's Context API shines. It allows for us to manage state globally and ensures consistency throughout the application. So So by using centralized state management, we can handle things like user progress, settings, theme changes, et cetera, in a scalable and really maintainable way. Now let's go ahead and see how an app like Headspace uses advanced state management to create a seamless user experience. Headspace uses React's Context API to centrally manage the theme UI components dynamically, The context provider encapsulates styling, all the styling for the properties for the various UI elements like the buttons, the cards, progress bars, which really enables the consistency and the scalability of the styling across the application. Now, this approach allows for theme variations and responsive design changes throughout the app without repetitive code. All right, now let's move on to the M and games. The M stands for memoization, and the key to this really is the key to ensuring our apps run smoothly. So memoization helps us prevent unnecessary re renders, improving performance, especially in dynamic applications. Now, looking ahead, and this is really where that modern optimization comes into play. The new React compiler, which is currently in beta, will take this further by automatically optimizing our apps. without the need for manual memoization. So we'll analyze component trees and apply performance improvements seamlessly. Now a good example of using memoization is Grammarly, where it is strategically employed in the suggestions section to enhance the efficiency of the real time analysis of the text. The component responsible for rendering suggestions is wrapped with React Memo, which ensures that it only re renders when they, when there really are necessary, when there are changes to the prop, specifically the typed input. Now, by doing this, Grammarly maintains high performance as it delivers instant feedback and suggestions, which really are crucial for a seamless user experience. All right, onto the E in games. Now the E in games stands for efficient rendering, which really is all about the right components at the right time. So with React Lazy and Suspense, we can load components on demand, reducing the initial load time and really improving the performance. Now efficient rendering techniques can help us manage heavy assets or really complex components in a way that doesn't block the user experience. So let's go ahead and see how an app like Duolingo uses these techniques to deliver smooth animations. In Duolingo, efficient rendering is achieved through react suspense component, which handles the loading of character animations. So suspense ensures that animations only render once when they are fully loaded, preventing for the that incomplete or laggy visuals during different interactions. All right, let's move on to the final letter S. S stands for social interaction, which brings a new dimension of engagement to apps. Adding social features allows users to do things like share achievements, compute with each other, and feel this sense of community. So social interaction encourages users to return not just for the individual rewards, but also for the fun of the competition. So let's go ahead and see how Duolingo does this exceptionally well with their leaderboard and social sharing features. For social interaction, Duolingo enhances user engagement. Additionally, Duolingo integrates a social aspect by allowing users to follow friends and see their language milestones. Alright, now before we go on to the live demo, I want to go through one application that really encapsulates the essence of my game's acronym through each one of the different elements. Starbucks, primarily built with React. It uses a progress bar to visually represent customers earning stars from purchases. And React State Management It dynamically updates this bar, reflecting real time progress. Now, challenges within the app encourages users engagement by offering bonus stars for specific actions, like visiting several days in a row. And these are managed through React components, ensuring that progress and rewards are accurately tracked and updated. Additionally, seasonal games are also integrated. offering prizes from bonus stars to vacations. And these utilize react for timely updates and interactive elements during promotional periods. Now the next letter a is advanced state control and Starbucks effectively utilizes reacts context API to manage the global settings such as locale and currency. It's approach ensures that regardless of where in the world the app is accessed, all of the current or the correct currency and the language adhere to the preferences due to the location of the user. The context API, it allows Starbucks to centralize state management for these settings, enabling a consistent and flawless user experience. Alright, on to M. The memoization, Starbucks does optimize its application performance by using memoization through React Memo and Use Memo. These techniques are useful for caching data that doesn't change very often, such as currency formats or menu item prices. And by preventing the re, by preventing these like redundant renders, re renders, Starbucks enhances the responsiveness of its app. And it ensures that users experience a quick and smooth interactions, even during the high demand periods. All right, on to the E. Again, this is efficient rendering and Starbucks faces the challenge of managing high volumes of user interactions, especially during its fun promotional event times. the app likely employs React strategies like lazy loading and suspense to handle these scenarios efficiently. using split coding techniques, Starbucks can load only the necessary pieces of code depending on the user interactions. And finally, let's move on to S, the social elements. Starbucks does encourage participants to send gift cards to their friends through the app. Additionally, some games users are encouraged to share their progress on social media during those provisional game periods. Okay, now that we've discussed the theory behind games, here's where we get to the fun part. we get to do some coding together. For this coding session, we're going to build a very simple app that will evolve into something a bit more engaging, with react and gamification techniques. So we're going to start small and we're going to add one little feature for each of the letter in games, my acronym. And by the end, we'll have a fun little gamified app with elements like experience, and social sharing. So to kick things off, we're going to start with this basic map app that I built in React. I've set up a new project here using Vite, and in this project I've cleaned up the default files a bit, so to keep things simple, for example, I deleted the Vite SVG file, and I emptied out the default styles in app. css, and I actually just got rid of index. css. Now here's what the project looks like now. So I have a simple app. css where I've set the app to have no predetermined margins or padding. And then I have a basic app. jsx where I've imported one component, which is my map component. And then of course I have my map component. Now inside of this map component, It uses Esri Leaflet to display a simple map of Washington, D. C. Now, Esri Leaflet is, if you're unfamiliar, it's a lightweight set of plugins that allows you to easily integrate maps using ArcGIS basemap styles. it really opens up the space for you to use different ArcGIS styles. It also actually allows you to use many other different ArcGIS capabilities as well. Now in this map component, I first use the use rough hook to store the map instance. And this ensures that the map is initialized only once and doesn't get like rein initialized every time that the component re renders. By checking if, the map ref is null, we do ensure that the map is created only on the components first mount next, inside the use effect hook. I initialize the map when the component first renders. And the map, like I said, is centered on Washington, D. C. with a set latitude and longitude, as we can see here. Now, Leaflet does go latitude, comma, longitude. Other mapping libraries do longitude, comma, latitude. Just depends. Now, I will then add the ArcGIS community base map here. To the map, and I, in order to do that, I have to use the vector basemap layer method from Esri leaflet. And the API key required to access the ArcGIS services is securely retrieved from the environment variable, Vite ArcGIS API key, using the import. meta. env. So I have my API key stored in my env file. And I pass this API key as a token to authenticate the request when adding the base map to the map with add to and then map ref current. And finally, I return a div with an ID of map where the map is rendered. And the height of this map, I've set it to 70%. Of the viewport height to ensure that it takes up a good portion of the screen with leaving some room for our gamified elements below. At this point, we have a fully functioning basic map of DC. And let's go ahead and run this and check it out. All right, so you'll see that the map center, the map centered on Washington DC here is displayed in our map container. And yeah, now that we have our map in place. We can start incorporating the gamified elements to enhance our user experience. Okay, so we're moving on to, the first letter in our acronym, which is G Games, our gamified components. in order to incorporate this, I'm going to start small. We're just going to add a progress bar to our app. this progress bar will track a user's XP and give them a sense of, progression. The concept is pretty simple. it's really just when the user performs some action, in this case we're just going to put in a button, that they'll then gain some XP or experience points and the progress bar will fill up. And once it's filled up, it will refresh itself, like leveling up. Alright, so in order to build this, we're going to start with a very basic progress bar component in our app. And inside of this component, the progress bar will take in one prop. And that will be the current XP, or the user's score. Now, we can calculate the percentage, filled by calculating the XP, out of the max XP, which in this case is going to be 100. And we'll use that value to set the width of the inner, what will be a div. and this will visually represent the progress. So after every 100 XP, We'll have it, reset. So next, we'll use a simple HTML structure for our progress bar. And this'll contain, this'll be two different divs that we'll use. One for the border, and one to show progress with a green filling. And next in my app, JSX, I'm going to import the progress bar component. and also to keep track of the user's XP value, we'll need to use states. So I'll set the initial state to zero, and then I'll add a simple click handler to update the XP. And when we click on the button, we'll add 10 XP each time. Now, below the map, I need to make sure I display this button and give it the click functionality. And I will also display the current XP value and my progress bar with the XP prop. Now let's go ahead and test this out. When we click gain XP, the button, we should see the XP increase. And the progress bar will fill up accordingly, resetting after every 100 experience points. Now this is a really simple example of a Gamify component, but even with this basic mechanic, users can feel a greater sense of engagement through the progress that they're making. gaining. Now to add more value to this, especially in a map app like this, I would say you could tie this kind of functionality to locations that, say, maybe the user discovers on the map, rewarding them with some XP for each place that they discover. So click on a place on the map, and they gain some XP points. All right, now that we've added our first gamified component, the progress bar. we're going to start thinking about managing state in a bit of a more scalable way. So right now this progress bar is handled locally using useState, which is fine for a simple app. However, as you scale your app and add more features, say levels, badges, maybe multiple map styles, sharing the data across multiple components will become a little bit tricky. So this is where advanced state control is going to come into play. And we're gonna use React context, API, and this will allow us to manage the state globally, making it accessible across all the different components. So we're gonna refactor our code. We'll first start by creating a new file called Game Context. And first we use the create context to create the game context. And this will let any component access the global state. Then we're gonna. define our initial state for our application, which is the XP value set to zero in this case. Alright, now we're going to the reducer function, and this is going to be handling, managing the state for our experience. Now, inside of the reducer function, we're going to have it listen for two main types of functions. First, this is going to be when we increment our XP value. It's going to preserve the current state using the spread operator, and then we're going to update the current XP by adding the amount provided in the action payload to the existing XP value. The second action will be reset XP, and this will really just reset the experience, or XP value, back to the initial state. And then, finally, we'll have a default, so any other actions, not recognized, we'll simply return the current state. Okay, almost done with our context. now that we do have the context and reducer set up, the next step is to wrap the app in the game provider. And this is going to make the global XP state, accessible to all components in our app. Okay. So we'll start by setting up the GameProvider. And inside this provider, we use the UseReducer hook, which takes two different things. The Reducer function we created earlier, and the initial state. The Reducer, that will help us manage state transitions based on actions, like adding XP or resetting the state. Alright, now next we are going to wrap the GameContextProvider around the Children component. It's passing in state and dispatch as the value. And this step is critical to allow that, access to all of the children, all components to have access to the state. All right. Now in the original version of our app dot JSX, we were managing the XP using the use state hook locally, and then we defined a local XP state and a handle click function to increment the XP by 10 each time. And the updated XP was then passed to the progress bar. But now we're switching to this global state management, which is managed by the game context. first to do this, we're going to, instead of useState, we're going to use useContext, and I'll also need to import the game context. Now, we'll use the global state objects containing the XP. And the dispatch. Fun dispatch function, to trigger state updates through the context of game context. Alright, next we'll go ahead and update the handle click function. So instead of directly updating the state with set xp, we dispatch and action with the increment xp, that type, and then a payload of 10. And this is handled by the reducer endgame context. All right, finally, we're going to replace the local XP reference with state dot XP. Okay, now that we've done all of this, the final step is to make sure that the game provider wraps our app component. So this is important because the game provider makes the global state available to all the components within the app. So we're going to do this by going to the main entry point of our app, which is main dot JSX. I'm going to wrap the app component in the game provider. All right, so in summary, now that we've done all of this, it's going to allow us to seamlessly pass XP to any component in our application that needs it. all right, so now that we've got our foundation with gamified components and advanced state control, we're going to move on to M. So the M, as we learned earlier, is membozation, and this focuses on optimizing the performance. So I'm going to do this in my progress bar. And again, this will prevent any unnecessary re renders from happening. So in my progress bar component, I'm going to bring in Memo, React Memo, and then wrap the component in Memo. So it will only re render when the XP prop changes. This really is a simple way to boost performance. components. And while it might really have a big impact in a small app like this, it really would be essential in larger ones. For instance, if we add a bunch more features like leaderboards, animations, multiplayer interactions, memoization can be really valuable. And of course, as we learned earlier, react recently introduced the react compiler, which will automatically optimize these components. So with a little bit of configuration there, all, we won't have to go in and manually use this react memo anymore. Now onto the E, which it stands for efficient rendering. And this is where we look at loading different components more efficiently, as the user interacts with the app. So again, we're going to do this, with one key strategy, which is lazily loading different components. And this really just means that we only load them when they're needed rather than all up front. and it does help with some code splitting, improving load times and that kind of thing in larger apps. Now for our example, we're going to just lazily load our progress bar, just to show kind of the functionality of this. So to do this, I'll use React Lazy to dynamically import the progress bar. However, React won't know to actually, it won't know what to display while loading. So we will need to import suspense and wrap the progress bar in a suspense component as well and show a fallback. And this fallback will be whatever shows while the progress bar is loading. So for instance, I'm going to go ahead and say loading progress bar here. So when we run the app, you'll see the loading progress bar. message briefly as React fetches the component asynchronously. We can see it there. All right. Finally, we're on to S. So now that we've optimized our app's performance, it's time to bring in a little bit of social interaction. Now this step adds some fun engagement by allowing users to share their progress with friends on social media. So to achieve this, I'm going to create a social share component. And this will let users share their XP on X, or formerly Twitter. Okay, so the component accepts XP as a prop, representing, again, the experience of the user. And this will be dynamically inserted into the social media post. So inside the component, we will define a shareOnX function, and that will generate a URL That will, be pre filled with the message for X, and it will also open it in a new window. Alright, so next we're going to add a Share on X button that when clicked, it's going to call our function prompting the user to share their experience. finally, we are going to export the component, and then we're going to integrate it. So we import the social share component into our app. jsx. We're going to render it just below the progress bar, and of course we're going to pass in the XP prop with that as well. Okay. Let's go ahead and open up our app and test that out. Okay, clicking on the share button here, we see that X comes up, and it's filled with my experience points. Awesome. Okay, so we've covered the games framework, adding features like XP tracking, progress bars, social sharing and optimizing, the performance, state management. And so all of these techniques are really, again, essential as our app grows. to wrap things up, I've compiled some resources for you guys. So we've got documentation for the links for React, Ezri Leaflet, and the React Compiler. and I've also got some links here to the code for the demo that we just did, the starter and final versions. So to access these links, you can use the PDF version of these slides at this QR code here. And that's all I've got for you guys today. So thank you guys for joining. I really hope that you feel inspired to add some kind of gamification. into your applications. Thanks and happy coding.
...

Courtney Yatteau

Developer Advocate @ Esri

Courtney Yatteau's LinkedIn account Courtney Yatteau's twitter account



Awesome tech events for

Priority access to all content

Video hallway track

Community chat

Exclusive promotions and giveaways