Rethinking state management in React

Thank you.

Thank you.

You're right.

I was building something and I'm like, why take the easy road?

You know, why not just piss off some people with my opinions?

So here I am to share a bit of that.

hello again, everyone.

My name is Keerthana.

KK is completely fine.

I live in Germany now.

People have a hard time pronouncing, aggressively Indian name.

So KK works.

and Yeah.

So before I, I go ahead with the rest of my talk.

I, would like a show of hands, how many people here have experience working with.

OG Redux so by OG I mean like stuff with middleware, saga, boiler plate, like show of hands, Oh, lots of people have been traumatized.

Wonderful.

And anybody here who, I've worked with Redux a little bit, in terms of building something, but I'm not really running a system in production yet.

Something like that.

Is anybody here.

No, nobody.

Nobody with fresh eyes.

I love it.

Anybody here who's planning I was just waiting for this talk after this talk tomorrow I'm gonna go build a system that I'm just gonna put into production.

Anybody like that?

No.

Wonderful, So I'm gonna start with the assumption that all of us to an extent have been like battle tested.

we've seen some stuff, right?

We have, oh, one more thing I wanted to ask anybody here with a code base, which is less than two years old, Excellent.

I love this.

Oh, there's a few people.

Yeah, that's good for you.

you're gonna learn some stuff.

So, I, come from a place where, the code base that I'm currently working with, so I have two projects which I'll be referencing.

The first one, it's quite, brand new.

It's like less than three years old.

So little bit, but not too much.

And the major code base that I'll be, the project that I'll be referencing, it is almost eight plus years old.

So there are stuff, there's part of it written in jQuery.

Yes.

and as is the, term, we all, we all worship at the altar of React in this room.

So at some point the people who created that website realized, time for me to move onto the newest, coolest thing, in 2020, they think React is the newest, coolest thing.

So, that's what happened to me with Yamdu.

They got in touch with me when they were like, Hey, we started this React thing and I don't think it's going too well.

And we heard that you talk about this stuff, so can you come over and, fix some of our stuff.

That's, my, role now.

And at Yamdu and, let's, go with the assumption that we are all going to build a brand new Marvel Super superhero movie.

that's the headspace that we are coming from.

So I'll be referencing when I talk about a project here with, we are thinking about the different parts which make a movie work.

that's what my examples will be coming from now.

So the problem statement is we need a library or framework, what, whatever you wanna call it, we need something that manages state between our components and React, right?

that's the headspace we are going into.

And of course, it's not just any old application, it's a complicated application.

It's running in production, there's multiple.

Scrum teams managing this stuff, it's not just a one person a job.

So it's not like you can just look through, a bunch of ideal performance charts and be like, Hey, this looks good.

Type to write this.

No.

If life were that, just simple.

we look at different things and there are real life kind of things that you cannot control, which is influencing it.

So that's, the side that I'm coming from in this problem statement.

And another thing that I really wanted to clarify before, we get into the deeper stuff.

When I mentioned state, it's not the local state of one component.

this is a cute version of a state.

Now, when I talk about state, all of the data in your application, right?

In this case, let me just show you an example.

So I talked about a movie, right?

All of this is state.

when you're talking about a movie, right?

All the actors, all the costume, and this is just four things guys.

Like there are sets, location scripts, all of this is data.

So this, that's what I'm talking about when it comes to state, like that kind of complicated data that you have to manage and any single change in state is basically, it, it changes the ui.

It changes, it responds to events, so that's what I mean when we talk about state in an application.

We are coming from a place where we have a legacy code base.

We want to find a tool and we want it to work for our particular circumstances.

So just because a tool works for me, and I'm gonna explain why something works for us that might not be the right fit for you, so I'm gonna explain why it works for us.

But you, can use this as a jumping off point to see, huh, does this really work for me?

Does this really work for my architecture, the way we have built things?

so this, is not, this one fits everything kind of a talk.

This is, this is how it works for you.

Does it really work for me?

Kind of a talk, right?

That's, one of what I want you to take away from it.

Another thing I have only considered almost two to three different state management for this.

things which were adjacent to what we already had in mind.

So we started out with Redux OG, like I mentioned with Middleware Saga.

That's the starting point that we had, and we tried out a couple of things pretty much adjacent to it because we have a very small, I, Yamdu is a kind of a small startup.

We only have one Scrum team, so it's very difficult to push people who are used to probably a good example would be if somebody is used to manual driving, right?

it's very difficult to push them into a hoverboard.

Automatic is just one step, right?

So it's really hard to push everybody in a team into a completely different thing.

So we were looking at things adjacent that we could just easily transition into and try to minimize tech.

That's where we are coming from.

Also, I don't have detailed examples because each of these, they, basically deserve their own workshops, right?

So it's, gonna be like a higher order think case kind of a thing.

So all that caveats down, let's, go for it.

In the case of why the team picked Redux to, to begin with or why?

Even if you look at React documentation, to an extent, I think even right now the official documentation of React has you wanna manage complicated state.

Have you heard of Redux?

I think they still have that somewhere in the official documentation.

And why do they have it?

Because, Like, I would compare it to how we had JavaScript before TypeScript, like you, whatever, you throw a JavaScript, there is a way to make it work.

And that's how Redux is, right?

Whatever.

How much ever complicated your, data that you have to manage, the state that you have to manage is Redux has a way to work it for you, but it's up to us.

So when there are a hundred ways to do things, it's on one hand, it's easy, everybody, you can find it, find a way to work it out.

But if you only use one or two, features of, if you don't need that kind of complication, then if you cannot maintain that kind of quality in your state management, that is when it, you really have to think I thought products were supposed to be good.

Why is my performance so bad?

Because you're not doing it the right way.

So, the more options you have, the easier it is to like mess up code quality.

So that's why we start rethinking Redux, right?

It's not because Redux itself is bad, or the Flux architecture is bad, it's because it has so many options that it's easier for us as human beings, to mess up.

Because that's, what humans do.

We kind of mess up.

So ideal use cases, a complicated app, which with complicated, different pieces of state is managed by different components, and the second point, let me give you an example.

So going back to this, I would like to change one act, right?

I'm gonna, I'm gonna switch out an actor, I'm gonna change Chris Hemsworth to Liam Hemsworth, right?

One, one little thing.

Now, if I, and, I may be the coder in this, the director has to know, the actors themselves has to know, let's assume that when this change happens, I want an email to be sent to the actor, right?

So that's an activity that's done after that change.

So if I want to have that kind of a, complex logic happening because of a state change, that kind of stuff is much more easier to manage with Redux.

You can tell Redux Hey, when this thing changes or when this API is called, I want...

every single time this API is called, I also want this logic to be, this function to be done.

Redux handles stuff like that.

And, the third point, we'll come, back to it a little bit more.

Oh.

Context.

So context is something that ships with React, it's a little bit of, it's a cute little bunny that comes with React.

that's how I'd call it if, you're going to the first React application I built, I remember using context and thinking, this is awesome.

Why?

Why does React even say that I need Redux, I don't need Redux!

Context solves anything.

and, you start with that.

And I don't wanna blow up my former colleagues, I don't wanna blow up their spot.

like I said, once some part of the old code base was written in jQuery, so when people are like, huh, context works.

we are coming from jQuery.

Why bother with Redux.

This looks so complicated.

Let's just use context.

Imagine where that ended up, for a complicated movie application, right?

Every time you change an actor, all the props and sets and stuff act related to it changes.

So what happens?

Everything re-renders, right?

and this is something that actually happened in the application.

they were like, context looks easy, let's go over that.

And then, oops, so many re-renders.

Maybe we want something more complicated.

So what is the ideal case for context?

I would still say that context can be used and context should be used in the right way.

For example, right now, especially in large applications, you have some, some global settings.

Yeah.

That's the ideal case for a context, right?

So if you have a application where you have different time zones, different currencies, brightness, dark, light, whatever it is, if you have those settings, which are, should not changed all the time, but once you change it, you want every element that, that requests it to change.

Yeah.

That's the kind of use case for context, right?

So you change it from dark mode to light mode.

Then literally every single component that requires like the style of every single component will change.

Or if you change currency, That will change.

So that's, really the ideal use case for context.

So just because context has a performance issue, if you overuse it doesn't mean that's something that you should completely avoid.

I think that it can be really used strategically in your application.

it decreases the amount of prop drilling you have to do.

And when used in the right way, I think sometimes context is really underrated because you start out using it, you find out the complexity with it, and then you are like, oh, I, used it once.

It was really bad.

It re-rendered too much.

I don't wanna touch it again.

Let's use Redux for everything.

We have redux already, right?

But sometimes I feel, oh, if you can use it in the right way, why not use it because it comes, built in.

You don't need to add a, different app, library to it.

You don't need to blow up your package dot json, for context, it comes shipped in, right?

So I would say that context is still something that we should not ignore it, it should be just sprinkled in the right amount.

So the big change that, that we made for, when it came to our state management was when we tried out the query model.

So again, this is an example, so in our example movie production, we are gonna assume that the ideal scriptwriter has only one script, or at least when he changes the script, he's just Hey, script is changed.

This is, we are only one draft at a time, right?

So at one point of time, we only need one API call.

ask the server, Hey, server.

A script.

I need a script, and the server gives the script back.

So also in terms of locations, I need a list of locations and when I select one location, it gives me the map of that one location.

So in terms of components that almost exclusively, they don't have any state on the user side, query is a very good option.

And the best part about the, I'm not gonna call it as just React Query.

The React query is just the one we tried.

query, I would say is a, methodology.

there are different libraries that, that use this query method.

I have personally not used, Apollo, I forgot what the name of it was, but, any way in which you can use this Reactive template, right?

Ask the server to handle everything and not handle the, complexity too much on the user side.

This is a great option, this kind of a query.

Yeah.

Especially when I'm front of an audience.

I forget the actual word, sorry.

When you have, React Query specifically, the thing I love about React Query is that it has a cache, which is really customizable.

So when I tell React Query, Hey, React Query, cache, all the list of locations, right?

React Query has these really nice features where when I change something in one location, it's oh, something has changed here.

Time to re-render, right?

That's the only time it re-renders.

Now if I tell the cache, Hey, please persist for 60 Minutes, cache does that.

If I tell the cache, Hey, please save a copy in local storage, it does that.

So I really like the amount of customization that React Query has.

that was really, the thing that sold us on it.

And it really helped the fact that, even though it was such a different paradigm compared to Redux, where, you store everything and you have that single, unidirectional kind of way in which you store stuff and you send the actions.

It removed a lot of the boiler plate saga middleware kind of stuff that we had to deal with.

So this really the, once I started using the query model, I really had to, rethink the way in which we set up our redux in the first place because I don't know about you guys, but when we originally had our redux model, we had, for every action we had individually to write, oh, there's a is fetching, there's a, has success, there's a has error, all of that we had to manage like individually from our side.

But when the query model came in, It came with a couple of booleans, and I just had to access the boolean.

Another thing with the query model that I loved was the way in which they handle the caching for each individual query.

So you have the query, you have the mutation, and each of them has a very specific key.

So if at some point when I am changing something in the script, I'm redoing the script, originally it was supposed to happen, everything in Germany, but I realized, December in Germany is hella cold.

I don't think I wanna shoot there.

I wanna move to lovely Sydney to shoot, right?

So I'm gonna tell the script, hey, the locations in the script have changed, so in the script component, you can have something like, Hey, if this change happens in the script, I want you to invalidate the key for the locations, right?

So you can have that where without going into the component, without changing anything in the locations component, I can just invalidate the query for component, for the locations and that fetch happens automatically.

So I don't even have to see It, it just happens in the background.

And the next time I move to locations, updated data is there.

So I really like the kind of re fetching, invalidation and all those, brand new functionalities that I saw with Query.

It really helped us and as probably quite evident by now, we were really leaning towards, so this is the architecture that we adopted it React to, not React query specifically, we'll come to that.

But we were really taken with this kind of approach towards, how we handle data.

Now, there is one drawback and that is, depending on how you've set up your front end when you use the query model, you might need to change some of your backend stuff because as you've noticed, this model is not really set up to manage a lot of, front end kind of state load, right?

you can store the data, but if you make a lot of changes in the front end, then that's really not where query shines through, right?

If you're gonna have a list of locations in the front end, and you're gonna also, like the only thing you get from locations is just the address, and in the front end, I'm going to make a map out of it or, any other kind of grouping out of it– if I, if there is more processing involved in the front end that doubles the load because now I have to fetch it from the server and again, do processing in the front end, that's, double the work.

So if you have set up your application in a way that a lot of processing happens on the client side, just so that you know it, it depends again on where you are from and a lot of other, if you are an application that, you expect to do a lot of offline management, right?

if you are an application that you don't know how good, your user's connection to the server will be here, that this may not be the right thing for you.

So every choice that you make in, state management, it's never going to be absolute.

It's going to be a trade off.

So just because it works, the query model works for us doesn't mean it might work for you because you really have to, I can show you a very cute example and you might think, oh, it re-fetches it very nice.

But when you implement it in your system, especially, again, this is why I started in the beginning saying, if it's brand new, you can think about architecture.

you can think about, oh, when I'm building it with query, I, can set up my backend in a way.

But if you have a zombie system already with five years of code and it's written in a specific way to manage things, is, the kind of paradigm shift that you're bringing with query, will that work for you?

Or will you have to redo a bunch of your backend so that every single time you make a change in the front end, it can handle that level of, calling, it can handle that kind of load.

So all of these are, to an extent, architectural design choices and be careful of these design choices that you make.

I'm gonna briefly take, take you through some of the other kind of things we explored.

Now, as you can see, I've used varied levels of gray, and that's because, React Query was what I researched in my team and we had the system where everybody in the team did a different thing.

And, as you can imagine, none of these made the cut.

And this is more like a curiosity.

Honestly, I do not even remember the last one, Zustand.

I remember seeing, it's really cute.

It's really small.

the, thing that sold us about Zustand was that it had a very small bundle size, but I think it was, also quite new, and we did not have enough documentation to really see how we could fit it in.

And I think it was pretty similar to Recoil as well.

Now I remember MobX and what happened with MobX again.

Humans, are fallible.

The person who implemented the MobX, it also has, I think some, something similar to that is called MSD.

And he mixed up the syntax to MobX and MSD.

And we spent three days like, why is this not working?

The documentation says it's supposed to work, but that's because we messed up the syntax.

This is us.

And the longest time that we spent was actually on, XState.

And the fun thing about XState is that it really.

Talk about paradigm shift, to an extent even React Query, I guess you.

You change the way you query things.

You ch you think about your, server querying approach, but when it comes to X state, it really forces you into a state machine kind of approach.

And when we tried that out, I really felt like, wow, you're not.

We are not living in the 2020s anymore.

We're living in the 2040s.

You guys state machines are really cool.

But when I said that, we have a very small scrum team, right?

I like state machines, somebody else likes state machines.

But for devs who have been working with, jQuery for the last six years devs who are like really junior, they really struggled with it.

that kind of, ex state machine thought process and going back to.

Yeah, going back to this, state machines are really cute when you can.

Like we, we can really map out all of the cases that happen.

But look at this, and again, like I said, these are only four things, so each of them are in interdependent of each other.

So if actor changes, all the other three change, if costume change, all the other three change, you, if I cannot get the costume for a guy, then I might have to, cast a child or a woman for that role.

all of these are interdependent.

So when we tried thinking about our application in terms of state machines, we realized that all the situations that could happen were way too complex and we could not finish it in the time that we had planned for this kind of, transition that we had planned.

So again, all of these options are out there, but the invisible cost of state management is that whatever tech debt you have, whatever team you have, whatever estimate that you have, you have to consider all of these when it comes to making a decision.

Because I would love to stand here and tell you, hey, State machines are awesome.

They are the future.

You should really try it out.

But if your system is too complicated and the rest of the devs in your team hate the state machine approach, maybe it's not worth it.

we really want our colleagues to not think about killing us.

So in the end, what we did, we decide to go with, we decided to go with RTK Query.

So RTK Query.

I'm not sure how many people are familiar with the Redux toolkit.

Any people have made the jump from OG Redux to Redux toolkit.

Oh, I see a few hands.

Awesome.

Awesome.

any for those of you who don't know, Redux, I'm not sure how recently, but they released this kind of, we know Redux has a lot of customization, but here is an opinionated way to do Redux.

That's what Redux toolkit is.

It's an opinionated way to do redux, And.

as a person coming from that, whole OG Redux outlook.

I, really loved the, way Redux Toolkit was set up, but my favorite part was that it managed to integrate a lot, not everything, but a lot of the querying functionality that React Query had, we really liked.

that worked for some part of our application, we were able to bring those in.

So when, I, tell you about how complicated the application is.

As you can imagine, the previous slide, all of those things with actors, characters, all those things, they're all interconnected.

Query will not work for those.

They're way too complex.

Every single change affects each other.

And trying query on that did just did not make sense.

But querying did work for like the scripts and the location section, right?

So for us managing to find a midpoint, which we could retain the redux architecture that we had, update it to reduce some of the boiler plate, but at the same time introduce query into some parts of the system, which could be like, query dependent, which could be server first, that really made sense to us.

And that's what gave us the shift towards it and also all the invisible things I mentioned for the people, for people in our team.

They felt that, oh yeah, this is the, this is a step we can take.

As compared to something like state machines is like one step here.

State machines was way over there.

They were just not comfortable, but moving from Redux OG to something like, okay, this is Redux, but with queries.

Yeah.

that's, that was a shift that worked for us.

And it might be different for your team.

we have only one, one Scrum team.

if it's a larger application with a lot more devs, maybe state machine works for you.

You have enough manpower to build it.

So all of these things that come go into, choosing state management.

I, even if I had one more r there are so many other factors and this is, as I said, just a jumping off point to make you think about it now.

Another thing I, really would like for you to think about is that after all of this coming back into Flux, when does Flux still work?

And at the end of the day, that's why we went for, for RTK Query because it still used flux under the hood.

And for us, Flux really made sense because if you go back to like where I said the use cases of Redux was, now that we've seen how context and query work, we can come back and when I tell you multiple components, what I mean is not just an individual component, but basically like a feature when multiple features have different requirements, and when, you're working with such a large and kind of complicated system with different moving parts, different pieces of zombie code that have who knows when it was written and who, how to manage it.

You know when you have that kind of a complexity, Flux is really nice.

whatever you throw at it, it can handle.

I'm really jealous of people who are starting from scratch, even now, maybe a year ago, because they really don't have to deal with that again, with zombie complexity.

But in the real life, as, you've probably seen in the talks all throughout yesterday and today, 80% of the Web still runs with jQuery, chances are highly likely that you have a lot of complexity in your code base, right?

So that's still why Flux makes sense.

But just because Flux makes sense doesn't mean you have to stay with the original architecture.

Now there's way to update it.

There's ways to improve the structure in a way that maintaining that structure, you can still improve how many actions that you do, how you hit the server, and all those other benchmarks that improve the performance.

Because as we know, React, the biggest source of performance issues is re-rendering.

And how we, how do we re-render?

We either change the props or we change the state, which means the data of your application is basically, how the most efficient way that you can manage your data is basically the biggest, way, which thing that impacts your performance.

So there is still ways to rethink how you, you manage the data, you manage the state of your application, but, be sure to think not just about the technical aspects and the technical costs, but also other hidden costs when it comes to rethinking.

And that's me.

that's all what I wanted to tell you guys.

look at the challenges, look at everything, and I really hope this, gives you a starting point into your own.

I'm, gonna say super, super easy state management journey.

Thank you.

Thank you

HI! I'M KEERTHANA (KK)

I'm a neurodivergent BIPOC software engineer from Cochin, India living in Munich, Germany.

PROBLEM STATEMENT

We need a library to manage state between components in our React application

React State 101

‘State’ of the application is how it responds to events in the UI

It is used to manage what users see, how the app looks, what data is stored

CAVEATS

  • We wanted to find a tool that worked for our circumstances
  • We only tried out a limited number of options
  • We wanted to find something compatible with our existing system

THE IDEAL CASE FOR REDUX

A box labelled "Redux" is connected by lines to four boxes labelled "Actors", "Characters", "Costumes", "Props"

Redux

CAVEATS

  • We wanted to find a tool that worked for our circumstances
  • We only tried out a limited number of options
  • We wanted to find something compatible with our existing system

What about x?

There a lot more options out there that we didnt get to check out. Some of them look super cool! :)

Examples

With 30 mins, don't have the space to get into proper code ‘examples. The features of individual options need to be explored with larger examples

THE IDEAL CASE FOR REDUX

Repeat of the earlier slide

USE CASES

  1. Complex apps with multiple states used in multiple places
  2. States are updated and refreshed often
  3. State updates require complex logic

REACT CONTEXT

  • When data needs to be accessible by many components at different nesting levels
  • The Provider re-renders all the consumers when its value changes
  • Built-in and beginner friendly
  • Suited for static data with infrequent changes, Ex: language, brightness
  • Performance issues when value is updated too often
  • Not designed to handle complexity

REACT QUERY

  • Ideal for projects with server-side processing
  • Features including automated refetching, invalidation, pagination support and more
  • Fetched data is kept in a cache that can be accessed by all components
  • Doesn't actually manage client-side changes in the state

MORE OPTIONS

Quick overview of my first impressions

XSTATE
  • Uses the concept of state machines
  • Paradigm shifting

MOBX

  • Uses the the observer/observable pattern to re-render components when their accessed data changes

RECOIL

  • Organize your data into a graph structure
  • Brand new

ZUSTAND

  • Small bundle size

THE IDEAL CASE FOR REDUX

Repeat of the earlier slide

REACT QUERY

Paradigm shifting. Reduces a lot of boilerplate associated with state management

RTK QUERY

Combining the features of both Redux and React Query Easy to integrate with the existing infrastructure

CONTEXT

Useful for project wide settings like user settings or session data

WHEN FLUX WORKS

  • When multiple components need to access the same application state
  • When you're working on a large application with several other people
  • When application state is updated frequently

This is just the starting point

Look at the challenges unique to your project and see which of these fit your requirements