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.