React Native Radio

RNR 241 - Redux Toolkit vs MobX-State-Tree Showdown

Episode Summary

Should you use Redux or MobX-State-Tree? Robin, Mazen, and Jamon do a breakdown of the various tradeoffs of these two popular state management libraries.

Episode Notes

Should you use Redux or MobX-State-Tree? Robin, Mazen, and Jamon do a breakdown of the various tradeoffs of these two popular state management libraries.

This episode brought to you by Infinite Red! Infinite Red is a premier React Native design and development agency located in the USA. With five years of React Native experience and deep roots in the React Native community (hosts of Chain React and the React Native Newsletter), Infinite Red is the best choice for your next React Native app.

Helpful Links:

  1. https://www.loom.com/share/9e3afe0547824e42bada06191e891ae1
  2. https://mobx-state-tree.js.org/intro/welcome
  3. https://redux.js.org/introduction/getting-started
  4. https://reactnativeradio.com/episodes/175-state-management-in-react-native-sLR6hN_v

Connect With Us!

Episode Transcription

Todd Werth:

Welcome back to React Native Radio Podcast. Brought to you by the US holiday, the 4th of July. Remember, Independence Day isn't just for getting drunk and blowing things up. You can do that sober as well. Episode 241, a showdown between Redux Toolkit versus MobX-State-Tree.

Jamon Holmgren:

Did you know that we got nominated for an award for this podcast?

Robin Heinze:

I heard about that. Yeah.

Jamon Holmgren:

Actually you told me.

Robin Heinze:

I did tell you.

Jamon Holmgren:

Let's just not feign ignorance here.

Robin Heinze:

Yeah.

Jamon Holmgren:

It was in my personal email and I don't really look at that as often.

Robin Heinze:

Yeah, I informed Jamon that we had been nominated for an award.

Jamon Holmgren:

This podcast was.

Robin Heinze:

The podcast.

Jamon Holmgren:

It actually was validating. I get these emails that are, "Oh, you've been nominated for an award. Just go to this website, pay us money, and then we'll put you on."

Robin Heinze:

We had to make sure it wasn't a scam.

Mazen Chami:

Oh, the token Nigerian prince.

Jamon Holmgren:

Hey, Mazen can say that because he's Nigerian. He originally is from Nigeria, okay people? Relax.

Mazen Chami:

Somewhere in Nigeria there's an apartment full of money that no one's claimed.

Jamon Holmgren:

Yeah, and here we are.

Robin Heinze:

Someone's just waiting like, "why does no one want this money?"

Jamon Holmgren:

Right? Yeah. But in this case, it was, I think legit, and it actually is legit-

Robin Heinze:

Yeah it is legit.

Jamon Holmgren:

Because Gant said that he's actually handed this award out before at React-

Robin Heinze:

Of course he has.

Jamon Holmgren:

It used to be React Amsterdam. Yeah, of course he did.

Robin Heinze:

Of course he has.

Jamon Holmgren:

It's now React Summit. But the award is most impactful contribution to the community.

Robin Heinze:

This is for The React Open Source Words 2022.

Mazen Chami:

I mean, who are the other nominees? We-

Robin Heinze:

We don't know.

Jamon Holmgren:

We don't know nobody as good as us.

Mazen Chami:

I was going to say spam their Twitter. Like we should win this.

Robin Heinze:

Maybe we're the only nominee.

Mazen Chami:

We'll find out on-

Jamon Holmgren:

That would be one way to win it, is to be the only nominee

Robin Heinze:

That's like, whenever we have an election, half the ballot is one candidate unopposed. That's just like a shoe in.

Jamon Holmgren:

Yeah, exactly. You know what I do in those elections? Because, generally I don't know anything about these local races.

Robin Heinze:

Yeah.

Jamon Holmgren:

I actually don't vote for the one person.

Robin Heinze:

The unopposed people?

Jamon Holmgren:

Just in case like there's some-

Robin Heinze:

I always read the pamphlet. Like I read their blurb. I look into them if they're like decent-

Jamon Holmgren:

Okay-ish then you vote for them. Yeah.

Robin Heinze:

Then I vote for them.

Jamon Holmgren:

My thought process is like, if there's someone who's deserving of a right in, they have a better chance if I don't vote for the ... I don't know, it's a dumb way to vote I think. Whatever. Other than stuffing the ballot box, I don't know. We just have to wait I guess, and see if we win this award.

Robin Heinze:

This episode will probably come out after the conference.

Jamon Holmgren:

Yeah, it will. That's true.

Robin Heinze:

But if you happen to be listening to this as a time traveler,

Mazen Chami:

And you're on the committee.

Robin Heinze:

Get tickets to React Summit.

Jamon Holmgren:

If you're on the committee, yeah.

Mazen Chami:

If you're on the committee that's deciding, I mean.

Jamon Holmgren:

Yeah.

Mazen Chami:

You know where to find us and we can arrange something.

Robin Heinze:

It's on June 17th, you can fly. I think all of the in person tickets are sold out.

Jamon Holmgren:

Yeah.

Robin Heinze:

But, there's a virtual option. Which is still, I think, infinitely available.

Jamon Holmgren:

You know, if we win this, then I can add award winning to our intro.

Robin Heinze:

Yes and all over the website. I helped Justin go through the website yesterday and I made sure the podcast was highlighted.

Jamon Holmgren:

Prominent.

Robin Heinze:

Yes.

Mazen Chami:

As it should be.

Jamon Holmgren:

That's awesome. We need all the advertising we can get.

Mazen Chami:

Well, I think that that is actually pretty exciting. A testament, by the way, to obviously all the people that helped make this possible but also to the listeners. Really appreciate all of you being here, hanging out with us.

Robin Heinze:

Don't be shy too. We love it. We love hearing from people who, who love the podcast.

Jamon Holmgren:

We do. We do. And we don't hear enough, even though we know you're out there. I see the statistics. This is getting downloaded and listened to.

Robin Heinze:

We get like one DM every couple weeks.

Jamon Holmgren:

Yeah.

Robin Heinze:

So yeah. Shower us with more praise please.

Jamon Holmgren:

You could see what our love language is here. We like awards and praise.

Robin Heinze:

Words of affirmation.

Jamon Holmgren:

So I'm Jamon Holmgren your host and friendly CTO of Infinite Red. I am located in the Pacific Northwest in Vancouver, Washington. No, I'm not Canadian. No, I'm not in Washington DC. I live there with my wife and four kids on three acres.

I actually got my tractor out the other day and the battery was dead. So I had to jump start it. But yeah, I'm starting that process of cleaning things up for the summer.

I'm joined today by my inconceivable. Co-hosts Robin and Mazen.

Robin Heinze:

Inconceivable.

Jamon Holmgren:

Inconceivable, yes. I guess, yeah. You're inconceivable in some fashion.

Robin is a senior software engineer at Infinite Red. She's located west of Portland, Oregon with her husband and two kids and has specialized in React Native for the past five or six years. Something like that.

Mazen lives in Durham, North Carolina, with his wife and little boy. He is a former pro soccer player and coach and is a senior React Native engineer also here at Infinite Red.

This episode is sponsored by Infinite Red. Infinite Red is a Premier React, native design and development agency located fully remote in The US and Canada. By the way, Robin, you did a good job reading this in the episode. I actually listened to the one that had just come out before we recorded this. And you both did a great job.

Robin Heinze:

I listen to a lot of NPR podcasts.

Jamon Holmgren:

Yeah. Yeah. I should, should have you read this really. If you're looking for React Native expertise for your next React Native project, hit us up. Why do I say React Native like every three seconds? It's mostly SEO spam.

Robin Heinze:

Also say Infinite Red, every three seconds. If there's ever a drinking game, if anybody is playing a drinking game during the podcast, every time we say Infinite Red and React Native.

Jamon Holmgren:

You'll be very drunk before we even get started.

Mazen Chami:

They won't even know what the topic's on.

Robin Heinze:

On the floor.

Jamon Holmgren:

I know. That may be actually the way to go. It's probably the easiest way to become award-winning is to just get everybody drunk. Where was I? I doesn't matter. We're the React Native radio podcast. All right. Let's move on. Let's get into our topic.

We have actually a topic that's near and dear to my heart. It could ruffle some feathers. I don't know. What do you think? Do you think it could?

Mazen Chami:

I think so, maybe.

Robin Heinze:

I mean, it's always a divisive topic. No matter how many times it's been debated.

Mazen Chami:

The program is ... are weird.

Robin Heinze:

It's still divisive.

Mazen Chami:

It's true.

Jamon Holmgren:

It's a very opinionated topic. I would say. I think everyone has their opinion and they like barricade themselves behind it.

Robin Heinze:

Well, because it's, I mean-

Mazen Chami:

It does happen.

Robin Heinze:

It's like Flutter versus React Native it's something that you spend a huge portion of your time using. You get entrenched and when someone questions your choices, then it sort of gets at you.

Jamon Holmgren:

It's a personal attack.

Robin Heinze:

Yeah.

Jamon Holmgren:

So the topic is Redux Toolkit versus MobX-State-Tree show down. Now, before we start, I should say I do need to put out a disclaimer, I think. It's important to note the conflict of interest here. I am the primary maintainer, for better or worse, of MobX-State-Tree.

Robin Heinze:

How much time would you say you spend maintaining that there, Jamon?

Jamon Holmgren:

Let's move on. So I'm trying to be unbiased.

Robin Heinze:

It doesn't need a lot of it, it's fine. It's done. It's bill. It works. It's stable.

Jamon Holmgren:

Well, we'll actually talk about that a little bit, a little later, we also use MobX-State-Tree in our ignite boiler plate. So we've been using it for ... at Infinite Red, where we can for the past, I don't know, five years, something like that.

Robin Heinze:

So we don't claim to be unbiased.

Jamon Holmgren:

Not at all.

Mazen Chami:

Not at all, no.

Robin Heinze:

However, we have spent, Mazen and I, did spend the past year on a project using Redux Toolkit for a client who determined ... they chose the stack. So they decided on Redux Toolkit. So we used Redux tool for a year. So we have used it on a daily basis.

Jamon Holmgren:

In depth. Yes.

Robin Heinze:

Yes.

Mazen Chami:

Yeah, very in depth. And it was nice to transition to it because I'd heard a lot about it and I think it'd come up not long ago, ish. We used it in depth through this app and this app's in production now, it's great. So having that extra context behind all the other stuff we've used, I think it was very helpful.

Robin Heinze:

It's really nice to know a lot about both.

Mazen Chami:

It's like, know your competitor.

Jamon Holmgren:

Absolutely. We did an episode on state management before. We did talk a lot of MobX-State-Tree then as well. And that was in, actually our second episode, right after we took over React Native Radio 175. So, go check that out if you want to hear us go pine about it prior to this.

One last note, before we get started, we're not going to cover Redux Toolkit Query, RTK query. That is part of RTK so, I should mention it. It is sort of a competitor to React Query. But it's a little outside of the scope of what we're trying to do here, which is more of the state management, the local state management. I would like to do a little bit of a ... maybe do an episode on RTK Query versus React Query versus other options. We're going to have plenty to go over in this one too. It's probably going to be kind a long one.

All right. So you mentioned that you've used Redux Toolkit, Robin, what else have you used for state management systems so far?

Robin Heinze:

Well, Infinite Red used old school Redux when I first started learning React Native with the help of ReduxSauce, which is a package that we produced.

Jamon Holmgren:

Yeah. We actually created that.

Robin Heinze:

Yeah. We created ReduxSauce, which added, sort of took away some of the boiler plate of traditional Redux. I also did one client project where it was truly old school Redux. No helpers, no anything. Then of course I've used MobX-State-Tree and now Redux Toolkit and I've also just used context and internal state in React.

Jamon Holmgren:

Yeah. Those are kind of the usual suspects there. So you've, you've gotten the whole gamut. Mazen, what about you?

Mazen Chami:

I've used kind of plain old Redux, at one point Redux Toolkit. Used context in some regards MobX-State-Tree. I guess I could kind of throw this in here, I did use React Query as a replacement for state management. That was more of like a play, not playground, the app actually did go to production with it. It was just kind of good to see how that happened and it was leveraging GraphQL. I guess you could say, what's it called, stateless, but state management-less, but using a different tool.

Jamon Holmgren:

So you kind of rely on the server's state, I guess more?

Mazen Chami:

And the caching. It was more of a web app that ... where the users machine learning would run its stuff kind of overnight. And then at like 8:00 AM, the data was ready. If it was past 8:00 AM and you haven't fetched your data, it would re-fetch and there's no need to re-fetch after that. So it always pull from...

Jamon Holmgren:

Because it's not going to update.

Mazen Chami:

Yeah.

Jamon Holmgren:

That's an interesting use case.

Mazen Chami:

There's no point. Yeah. So that's when I was like, 'You know what, maybe there's no point in adding all this extra fluff.'

Jamon Holmgren:

That's a totally valid way to go. For me, I've used a bit of Redux. I didn't do a lot of Redux back when we used to use it because my job was different at that time. I was running operations more so than being in the tech. I actually became CTO later at Infinite Red I've of course used MobX-State-Tree a lot because I've shifted more into our tech stack once we've switched over. I have used mob ex by itself, some, which has been very interesting to dive into that. And we will, by the way, talk about differences between some of these things. We're not going to go too in depth with this but just to kind of give people an idea of what we're talking about.

I have built things with useState, useReducer, useContext as well. I even built my own little thing. It was kind of on top of MobX and MobX React but it was using ... I had a Firestore app. So using Firestore to kind of control a lot of the state on the server side.

So yeah, we have a fair amount of experience here, I would say, across the gamut of this. High level Redux is like Mobx. This isn't a perfect analogy.

Robin Heinze:

It's an analogy.

Jamon Holmgren:

Yeah.

Robin Heinze:

Yeah.

Jamon Holmgren:

And Redux Toolkit is like MobX-State-Tree.

Robin Heinze:

Yeah.

Jamon Holmgren:

Redux itself-

Robin Heinze:

One is like the base and one is like the-

Jamon Holmgren:

Right.

Robin Heinze:

... The flavor on top.

Jamon Holmgren:

I would say Redux is probably halfway between MobX and MobX-State-Tree. And Redux Toolkit is a bit beyond MobX-State-Tree because it includes the query part of it too. But that's kind of like the scale we're talking about.

For the purposes of what we're doing today, we're going to be talking about Redux Toolkit minus the query part versus MobX-State-Tree. Let's talk about RTK first and let's talk about, kind of the pros, cons, what it does, overview it, that sort of thing.

Robin Heinze:

Yeah. So if you're using Redux Toolkit, the general flow of data looks like you have a store, a primary top level store, and then you have what are called slices. So like small chunks of your store that sort of compartmentalize your state into business areas, feature areas. Then, in your views, you can select state from your stores and you can dispatch actions. Which, change the state in the store. Then you can also utilize a secondary library, thunk or sagas, I think are the two primary-

Jamon Holmgren:

Redux sagas. We used to use that as well.

Robin Heinze:

Yeah.

Mazen Chami:

Yeah.

Robin Heinze:

Yeah. Redux saga and Redux thunk, which will fetch data from external sources, APIs, what have you. Then your store or your slice will listen for those actions to complete and update state as necessary. Then you can also dispatch those thunks directly from your views as well.

Jamon Holmgren:

Again, you know, this is kind of my biases coming out but when I listen to that, I'm just hearing lots of concepts that if you haven't used Redux, you have to learn.

Robin Heinze:

What's a slice? What's a thunk? What does dispatch mean? What's an action?

Jamon Holmgren:

Yeah.

Robin Heinze:

Yeah. It's true.

Jamon Holmgren:

Selectors.

Robin Heinze:

What's a selector?

Jamon Holmgren:

Yeah. All this stuff. It's like they make up their own terms for all these things. One of the things that is pretty cool about it is that it ... like once you get over the hump of all those things, then scaling up your state management across a big app is just using all of those concepts over and over and over and over and over.

Mazen Chami:

One quick note, like kind of going over what Robin said, if you're using Redux, kind of linking it to Redux Toolkit here, just so you kind of get the full, full lay of the land. If you're using Redux, you'd remember stuff like actions dot type, and that's kind of how things essentially listened to whenever there was a change. Then the reducers would then go and update the data.

The difference here with Redux Toolkit is, you're overarching slice, think of it as like a dot then chaining kind of, like how you would chain a promise, something very similar to that. Where, you would have your dot, you'd have your state and then you'd have reducers. Within those reducers, that's where it's listening to your API, your thunks or sagas. Whenever that changes, that's where you would make your update. So we're going away from what would be a switch statement to something within a, almost like a chain, within the slice.

Jamon Holmgren:

So the API is different. The ergonomics are different, even, of how you approach them.

Robin Heinze:

Yeah. I will say, it feels very different-

Jamon Holmgren:

Agreed.

Robin Heinze:

Mm-hmm.

Jamon Holmgren:

... using Redux Toolkit than it, than it did using plain Redux. Other than the terms kind of being the same, I couldn't have told you I was using the same state management library.

Yeah. Interesting. Essentially, they were trying to address a lot of the concerns and criticisms of Redux, which was too much boiler plate. Primarily.

Robin Heinze:

There still is quite a lot of boiler plate. It's less. It definitely has been reduced. You still have to think of all, remember all, the different places you need to make a change in order-

Jamon Holmgren:

Right.

Robin Heinze:

To do one thing. Say, I want to keep track of a new piece of data. You have to remember the like three or four different places you need to go make a change in order to complete that chain.

Jamon Holmgren:

Yeah.

Robin Heinze:

Of like, fetch, update, store. Like yeah. There's a lot of places.

Mazen Chami:

Yeah. I remember with Redux always forgetting, whether it was the action type and it never listening to it and stuff like that. There was just a lot to copy over, back and forth. And well, given that they've kind of improved on it's still pretty much the same. Like if you're working on a new app or you're creating a new store, let's say, slice in this concept, you're still bringing over a lot of boiler plate stuff. But, it's simplified where instead of over multiple files, you almost could be in one file per store. In the past everything was kind of just split up. Now you could say everything is in one, as far as the state management part of things, all in one file. Yet, it's still could be a larger file for you.

Robin Heinze:

It could be like three, four places within that file.

Mazen Chami:

Correct? Yes. Yeah. All those like, splitting up into multiple files, are pretty much in one file spread across the entire file.

Jamon Holmgren:

Let's talk about the pros of Redux and RTK to start with, because we're really comparing a lot of these things back and forth between MobX-State-Tree and Redux, RTK. So first off they're very popular. Like it's the most-

Robin Heinze:

Hugely, hugely popular.

Jamon Holmgren:

The most popular state management library for react.

Robin Heinze:

Almost the default choice.

Jamon Holmgren:

Yeah. Just about.

Mazen Chami:

Everyone would probably expect you to be using one of those.

Jamon Holmgren:

Right.

Mazen Chami:

Before even using a new one or a different one.

Robin Heinze:

That obviously comes with advantages. I mean, it's all over stack overflow, it's all over. Like there's so much support. The documentation is great. There's-

Jamon Holmgren:

Blog posts.

Robin Heinze:

Yeah. Blog posts, articles.

Jamon Holmgren:

Yeah.

Robin Heinze:

There's a ton of learning resources and support for when you have issues.

Jamon Holmgren:

Big community. These are things that we actually argued were in favor of React Native compared to Flutter. The big community, the ability to hire for it, things like that. There is a lot that you could say is going for it.

I would say their documentation is very, very good, if not great. They've definitely put a ton of time into it.

Robin Heinze:

It's very good.

Jamon Holmgren:

Excellent documentation also very good integration with dev tooling. These are really, really important.

Robin Heinze:

You'll find like vs code extensions.

Mazen Chami:

I do like, kind of going back to the documentation, sorry that-

Jamon Holmgren:

Yeah.

Mazen Chami:

Every aspect of the documentation, if you're looking for a certain piece of it has simple examples of how to do it in both TypeScript and JavaScript. I think we still forget that a lot of people still use JavaScript. I think they've, they've put a lot of effort into making sure the documentation covers all.

Jamon Holmgren:

Widely accessible.

Mazen Chami:

Yeah, there we go, widely accessible.

Jamon Holmgren:

And just defaulting to only JavaScript leaves out the Typescript side of it. Exactly.

Mazen Chami:

Yeah. Very good Typescript support actually. I remember that being one of the things.

Jamon Holmgren:

Yeah. Things generally work pretty well. You don't have a lot of weird errors and stuff.

Robin Heinze:

If you've like followed the documentation and like you understand the terminology and you're implementing it as expected, it's pretty rare to get some just like funky error that you have to Google spend a lot of time debugging.

Jamon Holmgren:

Let's talk about the cons.

Robin Heinze:

We've touched on some already. There's still is a lot of boiler plate despite the fact that there's less boiler plate than there was before. We've also talked about the, all the new, sort of, conceptual things, reducers, slices, selectors, thunks, sagas.

Mazen Chami:

Actions.

Robin Heinze:

Yeah. All these terms that don't necessarily match any mental model that you would already have.

Jamon Holmgren:

Yeah. And speaking of selectors. I was actually meeting with a friend, a developer, who wants to convert over a pretty large Redux powered app over to MobX-State-Tree. So he was just asking me a bunch of questions.

He showed me a file that was a 1400 line selectors file.

Robin Heinze:

Oh my God.

Mazen Chami:

Wow.

Jamon Holmgren:

This was just one of their many files that had selectors in it. I just made a comment as we were kind of sliding through it. I said, 'Yeah, you just delete this file and not replace it when you use MobX-State-Tree.' So this was one of those things that is just, I guess, I'm going to skip ahead actually in my notes here to performance because that's why selectors exist. Is because, you don't need every piece of data in every component. So when you have a global store like this and you're passing it around, you need to make sure that it's performant selecting only the stuff that you need. Unfortunately, you have to do that manually in Redux, in RTK

Robin Heinze:

Selectors break my brain too.

Jamon Holmgren:

Yeah.

Robin Heinze:

Like the way they're defined, it's like a function which then passes its return value to a new function. And you have to keep track of like what arguments each function needs and it's confusing.

Jamon Holmgren:

Yeah.

Robin Heinze:

Anyway.

Jamon Holmgren:

Slices also, I would say, are ... and this kind of goes to one of my main criticisms of Redux. It's like, because they have made certain trade off decisions, they're like, okay, we're going to have one store, one big store. Now people want to divide this up into ... They don't want everything in one store. So now, how do you effectively design a store that can kind of like isolate pieces?

Robin Heinze:

You call it a slice.

Jamon Holmgren:

Invent a new, yeah, invent a new concept. Like every time it's inventing a new concept,

Robin Heinze:

It's still a store, but we're calling it a slice.

Jamon Holmgren:

Exactly. I kind of get why they're calling it a slice, but it's sort of like thinking in terms of the implementation rather than what people ... how people would mentally model this though. That's just, yeah, definitely, one of my criticisms.

Thunks and sagas are, first off, why are they called thunks and sagas? You don't know what that means.

Robin Heinze:

Saga. I can kind of picture why it's called a saga. I can like, I can work it out.

Jamon Holmgren:

Yeah, I guess so.

Yeah.

Robin Heinze:

Thunk? No idea.

Jamon Holmgren:

Yeah. I guess so.

Robin Heinze:

Absolutely no idea why it's called a thunk.

Jamon Holmgren:

I will say they're easier to Google.

Robin Heinze:

Yes.

Jamon Holmgren:

And it is true.

Robin Heinze:

It's true. They are easier to Google.

Jamon Holmgren:

That is a piece of this. And then actions. So both MobX-State-Tree and Redux have actions.

Robin Heinze:

Action is reasonably self-explanatory.

Jamon Holmgren:

Action is reasonable. Yeah.

Mazen Chami:

Yeah.

Jamon Holmgren:

Now one of the pieces of this also is that Redux tries very, very, very, very hard to be immutable, like all the way through. Which, forces you to do a bunch of back flips to do anything. Of course, I'm actually not a immutable Maximalist, if you've followed me at all. I think immutability has its place, but JavaScript is mutable by default for a reason. We can talk about that some more but people will ... I guarantee you some people, including some very senior developers who are listening to this right now, will have a visceral reaction to me saying mutability is not bad. They'll be like, 'Oh no, no, no, no, no, you can't do that. Well, that's, that's a recipe for disaster.'

Robin Heinze:

Everyone has a story of some like horrible bug,

Jamon Holmgren:

Yeah. Supposedly.

Robin Heinze:

Yeah.

Jamon Holmgren:

I'm not going to get into that. I can do a whole episode on mutability versus immutability.

Redux has kind of bought into that. Man, I'm really trying not to be too negative here. I'm really trying. Redux has really decided to make the trade off. That immutable, everything is the way to go. Now, in RTK they use Immer and that makes things feel a lot better while still being immutable.

Mazen Chami:

You saying like, you're trying not to be biased here, Jim. I think we're just pointing out the new concepts. There are a lot. Right? Given that, Robin and I had the first hand experience with it, I think the best thing for anyone to do, especially when we're ... maybe this is something to say at the end of the episode also. But, do a simple app with both of these, for example, and then try it out for yourself.

Jamon Holmgren:

Yeah.

Mazen Chami:

Get Ignite, get used to MobX-State-Tree and how it's fetching data and then maybe convert, Ignite over to Redux Toolkit and just see the difference for yourself. Because-

Robin Heinze:

It could come down to personal preference too. Like there's-

Mazen Chami:

Exactly.

Robin Heinze:

This isn't an entirely objective thing.

Mazen Chami:

No, it's not.

Robin Heinze:

What's best for one person in one app could be different than what's best for another person in another app.

Jamon Holmgren:

Well, like we talked about in the Flutter versus React Native thing is, a lot of it comes down to the trade offs that you make, the trade offs that you decide. Also better, isn't always better because there are different things that apply to this.

But, coming back to Redux so I can keep on ... so I can keep talking about this. It also subscribes very much to the Flux pattern.

I remember when Flux came out and the initial, first off, it was just sort of a concept. There wasn't even a library. Then there was like a Flux library. There was one called Reflux, which was like the worst name ever.

Mazen Chami:

Reflux, I remember that.

Jamon Holmgren:

It was terrible. I shouldn't say it's terrible. The name was terrible and it also was kind of clunky. Redux came out and actually simplified it quite a lot. Which, shows you how complicated the Flux pattern was to start with.

I sort of feel like the Flux pattern is like programmer egghead, brain kind of gone wrong. You let the PhDs have a little too much freedom here. All these concepts, instead of like real world people sitting down and building apps.

Robin Heinze:

So can you give everyone just a quick TLDR of what the Flux pattern is if they don't know?

Jamon Holmgren:

Part of the problem here, like, it's actually difficult for me to even explain. Even though I've studied it actually fairly a lot.

Robin Heinze:

That's how complicated it is.

Jamon Holmgren:

That's how complicated it is. But I'll try. Okay. The idea behind it was essentially that the more your app grows, the more complex kind of the different pieces that are reaching into your app as far as like state management are concerned. You have like data being updated from different places in different ways. It's sort of like a bidirectional data flow. You have data coming from right from components and then two components.

Robin Heinze:

The view updates the store and then gets data from ... also gets data from-

Jamon Holmgren:

No the store updates the view.

Robin Heinze:

Yeah, the store updates the view. Yeah.

Jamon Holmgren:

That was coming with like Angular and Ember to some degree and things like that. Flux tries to solve this by making unidirectional.

Robin Heinze:

Which is why you have actions and dispatchers.

Jamon Holmgren:

Yeah, exactly. You have kind of like this ... the classic circle. Where you have user interaction hits, you have your action creators that then hit, make an action.

Robin Heinze:

Oh my gosh.

Jamon Holmgren:

Then that hits a dispatcher.

Robin Heinze:

I had forgotten about action. You had to keep track of your actions and your action creators.

Jamon Holmgren:

Yeah. You have your store and then once your store updates, then you have change events that hit.

Robin Heinze:

Yes.

Jamon Holmgren:

Then those finally go to the react views. It was just, it was like, it was an interesting idea. It was based off of Elm. And I did some Elm. I'm familiar with this pattern.

Elm had to do this because there was literally, like, the language forces you to do something like this. That's okay. Like, I didn't mind it anyway.

Let's not get too deep in the weeds with that, but it kind of gives you a sense. Now, Redux actually made this simpler. It like simplified some of the concepts down, skipped some steps, made it a little easier. That's why it won because the React team was saying, you need to use the Flux pattern and the best, the easiest library to use the flex pattern was Redux.

Now with that said, there were some other ideas out there. Certainly observables and reactive programming were out there but people were sort of, a little scared of it because again, the eggheads sort of got too much control over that part of it as well. There wasn't really an easy way to do this.

I should mention before we get into MobX-State-Tree, one last thing too, performance. It's actually pretty easy to write poor performing RTK code.

Robin Heinze:

Yes.

Mazen Chami:

Mm-hmm (affirmative).

Robin Heinze:

It's very easy.

Mazen Chami:

Very true.

Jamon Holmgren:

You end up writing code to fix that issue through selectors and some other things. I think that this is actually, for me, one of the biggest criticisms I have of Redux as well as one of the biggest places I love having MobX and MobX-State-Tree.

Let's get into MobX-State-Tree. I do want to, really quickly, when we're done with this, go back and briefly touch on the pros again of Redux. There were some really important things in the pros section that we shouldn't forget. The cons sound really bad but there were some good things. Let's talk MobX-State-Tree. MobX-State-Tree, you load your data and you can have essentially a function, a method I guess, in your store.

Robin Heinze:

Let's start with, first of all, you have stores. That's like the-

Jamon Holmgren:

Correct.

Robin Heinze:

The fundamental.

Jamon Holmgren:

Okay. Let me back up.

Robin Heinze:

Yeah.

Jamon Holmgren:

Yeah. You have stores. You can have multiple stores. A store instance, you could have 5,000 store instances, if you want. A store. instance is literally just a model that contains other models. We just call it a store by convention but you actually define it using type dot model. A store is just a model.

Models can be any data model, custom types or even like type dot string type, dot number. Or it could be a custom type that's an object that contains other things.

Robin Heinze:

It's very, OOO reminiscent.

Jamon Holmgren:

It is actually, object oriented kind of focused.

Robin Heinze:

It constantly reminds me of rails. An active record.

Jamon Holmgren:

Yeah. It maybe that's why I like it.

Robin Heinze:

Yeah. From the very beginning, when I first learned about it, I was like, oh, this seems like active record. It still reminds me of active record.

Jamon Holmgren:

Totally. Then you can pull that data into your store. Then in your components, if you're using react or sorry, MobX react, which is one of the coolest libraries ever, it just watches whatever you're accessing. You don't have to write a selector. You just use it, you go like user dot name and it now knows anytime that name changes in your user model-

Robin Heinze:

But only name it. It doesn't-

Jamon Holmgren:

Only name.

Robin Heinze:

It doesn't listen for the entire stor. It only listens to what you have used.

Jamon Holmgren:

That's it.

Mazen Chami:

So if email changes, it doesn't care. And I think that is-

Robin Heinze:

Yeah. That's where you get the performance benefit.

Jamon Holmgren:

Yeah.

Robin Heinze:

Mm-hmm (affirmative).

Jamon Holmgren:

That's kind of like, like we're jumping ahead to the benefits of it, but it's like, even when you're just using it for one thing, it's very concise. Actually, let's just, let's go ahead and jump into that. We have some other things to talk about here, but let's jump into the pros.

I think it's fairly easy to learn. I put out a video, like a MobX-State-Tree in 20 minutes thing. If you watch that video, you're going to understand like how to use it pretty, pretty, well. There are a couple other concepts I didn't touch on but for the most part, the API service is not that big. It's a relatively tight API surface.

Robin Heinze:

All of the, sort of side, effects, the async actions, like accessing external services, that kind of thing, it's all built in. You're not dealing with a separate, like sagas and thunks are completely separate library to Redux. Both MobX-State-Tree, They're all ... it's all built in your models. Your models have their properties. They have their actions. It's all defined directly on your model.

Jamon Holmgren:

If you want to kick off an action that fetches data and updates the store, you just make it an async action just by literally putting the word async in front of it.

Robin Heinze:

Right. It's just a-

Jamon Holmgren:

It's a function.

Robin Heinze:

It's a function.

Jamon Holmgren:

It's just a function. There's no other concepts to learn here. It's just a function.

Mazen Chami:

I think you just mentioned, it's just a function, no new concepts. I think that's, that and also the fact that it's less boiler plate where you don't have to set up all that boiler plate to get it set up, I think is very, it's amazing. It's just small and you only set up what you want for that store. If it's one function, that's it, that's all you need to do. A view, not even, maybe not even something listening to an API, per se.

Robin Heinze:

The example I mentioned before where you're just trying to add a new piece of data that you want to track. In Redux, it would be like three or four different places that you then have to go update to like add all the links to the chain. And MobX-State-Tree, if I want to add a new property, I add a new property.

Jamon Holmgren:

Yeah, one line.

Robin Heinze:

And then I call it in my view.

Jamon Holmgren:

Yeah. If you wanted to add, in this hypothetical user model, if you wanted to add an age, you would just put age, colon.

Robin Heinze:

Number.

Jamon Holmgren:

That number.

Robin Heinze:

Yeah.

Jamon Holmgren:

And then over in your component where you're consuming the user, you would just do user dot age and you have it. It's observed, it's selected. Everything's, good to go.

I think that the concepts are a little more universal. We're not making up concepts here. There's models in stores. People understand what those are. In fact, we combine them. So that, they're just one thing.

Robin Heinze:

I think store is actually just a concept that Infinite Red invented.

Jamon Holmgren:

Sort of like, I guess.

Robin Heinze:

We name our models specifically like, something store.

Jamon Holmgren:

Yeah.

Robin Heinze:

If it's going to contain a list of other models.

Jamon Holmgren:

Other stuff. So like if you have a messages store, it'll have many messages, in it.

Robin Heinze:

Right, exactly.

Jamon Holmgren:

Yeah.

Robin Heinze:

It hearkens back to active record for me because you have-

Jamon Holmgren:

It does, kind of.

Robin Heinze:

You have tables full of records. And so each record is a model. And then you have a table which stores a list of them. So we have our like instance models and then we'll have store models, which then store an array of those instances. It's yeah. Very database-y.

Jamon Holmgren:

A few other things that you can do is runtime types. This is only during development, unless you want it in prod, but during development you can have MobX-State-Tree check to make sure that the types dot number that you are now setting, age equals 40, you actually gave it a number and not a string.

Robin Heinze:

Right.

Jamon Holmgren:

Or some other thing. So runtime type checking. Less important when you have type script. The nice thing is that it infers the type script types from those runtime types. So you don't have to do it twice. You just do it once and you're good. You obviously have your actions. You can do regular, which are just like, 'Make this change to the store.' You know, like 'Set current user to a new user.'

Robin Heinze:

Right. Usually make a bunch of like setter.

Jamon Holmgren:

Setter actions, exactly. You have async actions. Async action is just, like I said, you just put the word async in front of your function name, and now it's async, and you can await.

Then you have flows and flows are really, basically, almost identical to the async actions but the reason that they exist is because-

Robin Heinze:

Generators aren't they?

Jamon Holmgren:

They are generators. The reason that they exist is because in MobX-State-Tree, you can only update your store when you're in an action context. In other words, you can only do it in your action function. Can't update the store. You can't go user dot age equals 40 somewhere else. You can't do that. It will error. It'll be like, 'Hey, you can't ... There is a way turn that off.

Robin Heinze:

Which is why we have to make setter- yeah. That's why we make setter actions.

Jamon Holmgren:

That's why you'd have like user dot set age and then that's in an action. An async function, after your first await, jumps out of the action context. So with a flow, it allows you to just continue that and you can just continue to set things. It doesn't come into play very often.

I actually don't use flows myself very often if at all. It's just because async actions do everything I need as long as I have setters. That's sort of getting deeper into the weeds. Mazen, I know this is a feature you really love so I'm going to let you take this one. What about views?

Mazen Chami:

Views are probably the best part of MobX-State-Tree, for me. Going back to your example of user and age. Let's say we don't have age, repair returns, date of birth and that could be types.date. It's a date, we know it's a date. You have a view and on user profile, we want to display the user's age. You could just in your views do get, because it's a getter, user's age or whatever you want your function name to be. And then within that, just return converting the type dot date.

Robin Heinze:

Like do the math, calculate the age.

Mazen Chami:

Exactly. Do the math.

Robin Heinze:

Return it.

Mazen Chami:

Then just return that age and it'll display on your screen. And every time-

Robin Heinze:

And it cashes it

Mazen Chami:

Exactly. It caches it.

Robin Heinze:

It cashes it and waits, like if birth date changes, it updates the getter. But otherwise it's not recalculating it every time. It just like saves that.

Mazen Chami:

That idea of the views always still listening to whatever the one thing you're using. Because you kind of want to keep your views to listen to as little stuff as possible, I think. We're going back to performance. If that one thing changes, it'll update just that one spot that needs to be updated. Not everything kind of leading up to that.

This is like the most appealing. Well, not that the rest isn't, but I love this aspect of it and I think should be leveraged more with MobX.

Robin Heinze:

I definitely found myself trying to reach for that concept while I was using Redux Toolkit.

Jamon Holmgren:

This is actually the most poorly named concept in MobX-State-Tree. A view is like a view into your data.

Robin Heinze:

It's confusing.

Jamon Holmgren:

What I would probably call it is, yeah, like computed value derived state.

Robin Heinze:

Yeah.

Jamon Holmgren:

Or, you're transforming data before you consume it. So how would you do that in Redux? Or RTK?

Mazen Chami:

I think you'd almost have to write a utility function.

Robin Heinze:

Yeah.

Mazen Chami:

In your, let's say, your profile stats component, you would get the user object and then you would send it out.

Robin Heinze:

And like memoize it.

Mazen Chami:

Yeah. You'd send it out to utility function that memoizes it or even within the component. Just a memoized age that does that for you.

Robin Heinze:

Yeah. It would be very manual.

Mazen Chami:

Yeah. So going back to, quote unquote, boiler plate, you're just adding more to it to get ... the add-on views are basically utility functions. Whether-

Robin Heinze:

You can do some stuff with selectors, right?

Mazen Chami:

You can.

Robin Heinze:

Yeah.

Mazen Chami:

But I don't know if-

Robin Heinze:

But it's not as performing.

Mazen Chami:

No.

Jamon Holmgren:

I thought that there was a computed property feature in Redux, in RTK.

Mazen Chami:

If there was, I don't think we've used it.

Jamon Holmgren:

You haven't used that yeah. Okay.

Robin Heinze:

Yeah. It just says use selector.

Jamon Holmgren:

Selector's, I suppose. I guess from my perspective, it certainly is ... there's probably ways to accomplish this elsewhere but the cashing you get and then the reactivity is kind of the biggest thing that I wanted to bring up.

So with MobX React and MobX React Light, Light just doesn't support the class syntax for components. What you do is you just add ... you wrap your components in an observer function. So you're just, say like, export your observer version of this component. Then what that does is it ensures that any property that changes in any model or any store that is accessed inside of that component will actually then, in a targeted, way re-render that component.

If you had a little age ticker that was based on the ... it's based on the birth date and then someone goes in there, edits their profile and changes the birthdate. It will actually update that age component, the component that is consuming that age, based on the view. It could also do it just based on bare properties that you're accessing as well because maybe you have the birthdate shown somewhere and that also updates. But also it's only that component. It doesn't have to re-render the whole tree because hey, we're immutable so now everything has changed we have to go deep compare everything. Not to get after immutable structures again, but.

Mazen Chami:

Just real quick, with RTK, the use selector only selects the data for you. It's almost like, if you want to get the date of birth in your view, you'd use selector state, arrow, state dot, user dot data DOB or whatever. So to still convert it to age, you'd still have to have a utility function that does it.

Jamon Holmgren:

To make that change.

Mazen Chami:

You could put it within the selector still and there, constant age is equal to use selector, et cetera. There's still more work to be done to get you there instead of just having that one piece live in that one spot and it's visible.

Jamon Holmgren:

The last pro I'd like to throw out there is that MobX-State-Tree doesn't change all that much. I do see that as a pro.

Robin Heinze:

It doesn't change much because Jamon's the maintainer.

Jamon Holmgren:

It's true. I'm very careful not to make a lot of changes. A lot of people rely on this library and I really only want to make changes where it's really necessary. With that said, it is something that, this is getting into the cons.

We have a smaller community. Actually. I saw the creator of Angular actually submitted a pole request to MobX-State-Tree the other day. So he's using it.

Robin Heinze:

Nice.

Jamon Holmgren:

Yeah. That's kind of cool, but we have a smaller community than Redux. MobX-State-Tree and MobX itself are still the biggest alternative to Redux. Don't feel like it's small.

Robin Heinze:

Right, it's like-

Jamon Holmgren:

It's not small. It's small compared to Redux.

Robin Heinze:

I would characterize it as like a 80/20, 90/10.

Jamon Holmgren:

Yeah. It's in that range. Yeah.

Mazen Chami:

There are apps in production that are using it so.

Robin Heinze:

Well-

Mazen Chami:

Oh yeah, for sure. Tons.

Robin Heinze:

The ones we've made for sure.

Jamon Holmgren:

Not just that, there are some big apps out there that are using MobX-State-Tree, for sure. But yeah, we obviously use that at Infinite Red a lot too.

There are some gotchas, we talked about the async actions where it'll jump out of the action context once you do your first await. So that's why flow exists. But, there's a relatively straightforward way to fix it. And there's some heuristics you can use to make sure that doesn't happen.

Robin Heinze:

One of the biggest cons for me, is, it just, there tend to be a lot more errors and like things that just don't work the way you think they're going to work. I've had a lot of issues with the identifier and reference types.

There's, there's a feature in MobX-State-Tree where you can define a particular field as an identifier, like an ID. Then that lets you reference that object or instance as this identifier. If you have a list of that particular model type, it stores a list of its identifier instead of the entire instance.

I've had a lot of issues with like references being missing or in another tree. I'm not entirely sure what goes on behind the scenes but it can be tricky to get it right. Things like deleting objects can be kind of fraught because they disappear but then something's listening or referencing it somewhere else. You get a red screen. It gets tricky in situations where you're trying to paginate a lot of data. So you're like clearing out entire, entire stores and replacing the data and then you're dealing with sort of abandoned references. There can be some bugs in that area and it can be frustrating.

Jamon Holmgren:

References, which we didn't even touch on here until now, references are finicky in a way that I don't really like. I actually created a library to fix this.

Robin Heinze:

Oh, I didn't know that.

Jamon Holmgren:

Yeah. It's called MST reference pool. And what it does is-

Robin Heinze:

What did you do this?

Jamon Holmgren:

Oh, you know, just on my livestream at RN.live.

Mazen Chami:

During his free time.

Robin Heinze:

Clearly I didn't watch that episode.

Jamon Holmgren:

MST reference pool is, it's MobX-State-Tree extension, so you can just like load it in really easily, that lets you use references to a pool of model instances for any store. So it's sort of like an array type, like a type set array, that you can point all of your references to. It also has a garbage collector so you don't have memory leaks.

Let's say you have a bunch of posts, and this is all stuff that Robin just talked about, like this is stuff that she's dealt with. So when you add new posts, let's say you loaded in from the server or you created a new one on your app. You would use the functions that I provide to add these things. Then you can reference those anywhere in your tree. Basically everything in your data tree is going to be a reference, not the original post itself. The only time that the post is actually deleted is when all of the references are gone.

Robin Heinze:

Nice.

Jamon Holmgren:

When there's no references left, then it will finally delete it. Which is the whole problem with the, like, referencing dead objects, you deleted it, but then it was referenced somewhere else and things like. It solves all of those issues and it is very performant. It works super well for this stuff. I'm using it on a side app. It's great.

Robin Heinze:

Nice, I'll have to try it out.

Jamon Holmgren:

So this was definitely built to kind of fix a lot of that.

Robin Heinze:

We can cross that con off the list.

Jamon Holmgren:

You can if you use this library.

Robin Heinze:

Jamon fixed it.

Jamon Holmgren:

The gas buddy app, which we've been working on for quite some time, actually uses it under the hood for a lot of stuff.

Robin Heinze:

Side note, we worked on the GasBuddy app, which was number one in the app circle.

Jamon Holmgren:

Yeah. And probably we'll continue to be very high with the gas prices the way they are.

Mazen Chami:

Yeah.

Jamon Holmgren:

That is a huge complaint. One of the biggest complaints about MobX-State-Tree and I think I've mostly addressed it at this point, because of that.

Obviously I mentioned the smaller core team. Which, kind of goes with the community. I do actually have about 15 people on the core team, but not everybody is super active. So there are people watching the repo and things like that. I would say the documentation is one of the negatives.

Robin Heinze:

It's always been it's Achilles heel, I think.

Jamon Holmgren:

Yeah. I really need to go through and pretty much redo them.

Mazen Chami:

I think all documentation around the world can always improve and keep working on. I agree with you. But I think you giving it, putting it in the cons is a little bit, I kind of disagree with it because you also have the videos. I think the videos are very helpful of actually seeing it working.

Considering it's a small community, the documentation still ... I keep going back to the videos. The videos are great. You do a lot of content, whether it's the loom videos or your stream. Where, you do go through it and it's very helpful to kind of help with the documentation aspect.

When I was learning MobX-State-Tree, I was able to find the videos on the site and actually some videos of you talking about MSD. I was able to pretty much learn and understand the basics of MST through that.

Jamon Holmgren:

It might be a little overstating it to say that ... Redux needs a lot of documentation because of all the new concepts they've created. Do you really need a documentation about a function, a setter function? You know, stuff like that. Like you do need documentation for an action and reducer. You know, you do. You don't need it for a setter function like, as much. You could have a little bit.

With that said, I do think that the documentation of Redux is better, for sure. They put more time into it. We're really, way over time here. And I apologize to the editors here for this one. There's just a lot to go through. I'm going to really quickly hit a couple other things. TypeScript support could be better. The errors that TypeScript pops up are a little obtuse and that can be problematic in a lot of ways. I wish it was better.

Robin Heinze:

Yeah. The runtime type checking and typescript. Don't always-

Jamon Holmgren:

Exactly.

Robin Heinze:

Mesh very well.

Jamon Holmgren:

Because of that, that those are definitely some negatives I'm going to do a really quick reminder on the pros of Redux. They're basically the opposite of the cons of MST. Which is, that, essentially very popular, big community. Lots of do good documentation integration with dev tooling. There are dev tooling for ... there is pretty good dev tooling for MobX-State-Tree.

Robin Heinze:

I searched for a vscode extension It doesn't exist.

Jamon Holmgren:

But yeah, no vscode extension, all these things and the errors, a better typescript integrations better. Those are good reasons to choose Redux in RTK, for sure.

With that said, do not skip over MobX-State-Tree before you make that decision. I think that a lot of people, if they've experienced the two, are going to make the choice of, that MobX-State-Tree is a viable solution.

Of course use what's best for you, for your particular organization and your use case. We do prefer MobX-State-Tree at Infinite Red. We still do a lot of Redux. We still do a lot of RTK. We are not going to turn down Redux projects. We're going to continue to do that. If you use Ignite, MobX-State-Tree state is built in already. So Ignite is our React Native boiler plate. You can go check that out.

If you want to see a 20 minute MobX-State-Tree demo that will blow your mind a little bit, hopefully, we're going to put the Loom video in the show notes. I apologize in advance for the quality. Maybe I'll redo it before we do this. There's some issue with Loom and the quality didn't come out quite how I wanted it too. It's still quite watchable, you can still see everything that's happening. It's just not my ... our normal super high quality.

Thanks to both of you. Sorry. We're just trying to wrap this up quick. We have much more to say on this topic. We could spend another full episode on this if we wanted to. You can always go to RN.live to see me doing some live coding. You can see previous episodes, YouTube dot infinite dot red. You can join our community to talk about Redux versus MobX-State-Tree. Community dot infinite dot red. That's a slack community. Over 2000 React Native developers there, you can find us Robin underscore Heinze. Me, and I'm at Jamon Holmgren you can find Mazen at Mazen Chami. React Native radio at React Native RDIO.

Thanks to everybody who is helping out today. Producer editor, Todd Werth, assistant editor, episode release coordinator, Jed Bartausky. Designer, Justin Huskey guest coordinator, Derek Greenberg. Thanks to the Infinite Red did I hit all the points? I think I hit all the points. We're going to put some links.

Robin Heinze:

No one's listening at this point anyway.

Jamon Holmgren:

Check out the show notes.

Everybody's like, okay. All right. think we're done. See you later.

Mazen Chami:

Bye.