KBall MC’d a live show at React Amsterdam with a panel of 5 amazing React experts — Kitze, Michel Weststrate, Mike Grabowski, Vladimir Novick, and Andrey Okonetchnikov. It was a great discussion of state management solutions and the future of state management in the front-end.
Linode – Our cloud server of choice. Deploy a fast, efficient, native SSD cloud server for only $5/month. Get 4 months free using the code
changelog2019. Start your server - head to linode.com/changelog
Manifold – Manifold is the easiest way for you to discover, buy, and manage the best developer services for your application, regardless of your cloud. Discover the best cloud services for your projects at manifold.co
- Special thanks to React Amsterdam — the biggest React conference worldwide!
- Talk: State Management in the GraphQL Era
- Observables in MobX
- The Curious Case of MobX State Tree
- Aven Cloud Framework
- React Native Community
- Vladimir’s YouTube channel with bootcamps
Play the audio to listen along while you enjoy the transcript. 🎧
This will be a live show. Now, the structure for today’s event - we have all of our advice panel panelists; they have been answering people’s questions… I have a few pre-prepared questions, but I think broadly the opportunity here is to say “Okay, what’s actually bubbling up in the ecosystem?” If you’re answering questions, you’re doing workshops, what are people getting confused about, where are the challenges? Maybe we can get some of that content out to you here in the audience, and to the listeners who are gonna listen to this in about a week from now, when this will be published to the podcast.
So throughout this, if you have questions… You know, when we do a regular show, we broadcast it live and we have a Slack channel where people participate; well, you are our Slack channel today, so if you have questions, raise your hand up and I will try to get those questions in, and then I’ll repeat them so that everybody can hear it and the panelists will answer it.
Now, we do have only two handheld mics, so we are gonna be passing around a little bit; forgive us if there’s a little bit there.
First off then, let me introduce all of our panelists, and I’m gonna try and make sure that I pronounce everybody’s names right. On this side we’re starting with Michel, who is the author of MobX. Next we have Mike Grabowski, the co-founder of Callstack IO and a member of the React Native core team.
Vladimir, who is developer relations at Hasura and consultant and speaker.
Yeah, hi everyone.
Next, Kitze… Did I pronounce that right? I was having trouble with that earlier… He is the founder of React Academy.
No, I’m just a vlogger. [laughs]
Okay, and then Andrey, who is an independent web developer and designer.
[04:11] I’m gonna kick things off with one of my questions, because one of the great things about doing this is I get to my questions answered… I’ve noticed a big pattern in the React world - and the front-end world, broadly - that we have increasing numbers of solutions related to state management. It seems like we had the framework explosion and now we have the state management explosion… Answering questions in the Advice Lounge. We had experts here talking about MobX, which is focused on state management; one of the big motivating factors declared about hooks was “Oh, we can use this to better manage our state.” GraphQL, which is also essentially a state management solution… So I’m gonna aim this question at Michel first, with MobX - what are you seeing going on in the state management things? Are these solutions evolving towards each other, or what’s happening here?
I think the interesting thing in state management is still underway to be happening, and it’s the impact that Suspense and concurrent method have. I hear people saying that hooks and context and the recent APIs related to that change the game… I don’t think that’s the case. They made the APIs much better, but they didn’t fundamentally introduce new possibilities.
Sometimes people are like, “Oh, since there is now standardized context and standardized hooks, I don’t need state management anymore.” My simple answer is “Then you didn’t need it before”, because everything that you can do now with hooks and context, you could already do before. I mean, they made the API easier, they made composition easier, but they didn’t in essence introduce new concepts. I think in general that the state management game is still quite stable.
Ryan Florence was tweeting earlier this week that there’s basically three kinds of states - the state that is very specific to your domain, your persistent state, the things you send to the server, the things you want to keep if your office burns down, and that’s just the state that lives in your components, either abstracted away or not… And I think that separation still will remain, and that separation will be more clear, because there’s now less reason to use state management solutions for local state. But I think that’s the big separation - state that lives inside components and state that lives outside, because it’s generic for your application, or it’s required in many different places in the same application.
For later, I still see GraphQL mostly as a transportation layer, which might be sufficient if the data matches fairly directly with your machine for back-ends. And if there’s any transformation in-between, I still think that state management libraries are a great place to make that mapping between whatever you receive from back-ends and what you want to display, and usually what you want to enrich on the data.
Regarding GraphQL, I can totally relate to that… Lots of people overuse – well, with GraphQL, you obviously can switch everything to use just GraphQL for your local state, and it’s good, but some people overuse that. As you said, having GraphQL as a transportation and still keeping things in the state management solution that you use will probably make it easier to adopt GraphQL in your ecosystem, because you’re already using some kind of state management solution, and just adding GraphQL as a transportation layer, maybe using some local state for GraphQL and doing this connection with the state management that you use is something that is evolving right now. People use it more often.
[08:06] I gave a talk, “State management in a GraphQL era.” Maybe for two years I’m just recycling the same talk, because I believe that GraphQL changed the game of state management… And it’s a bit ironic, because I was preaching that hey, now with GraphQL you don’t even need a state management library on the client, right? And then eventually, when you have a complex client - let’s say you’re building a calendar, or something that has tons of interactions, then you see that hooks and context and everything that we have… I also get that question in workshops, “Can we replace Redux now with context and hooks?” No, because Redux is using those technologies underneath, in order to provide you with the Redux API. So you cannot replace Redux with hooks and context.
When you have complex state, you still wanna have something more advanced, for example something that has observables, now that Michel is here. But whenever I have some more complex state management and I have a model that has more than 600 lines of code, I’m still gonna reach out to MobX or mobx-state-tree to handle that code, instead of handling it with hooks.
So GraphQL is solving 90% of the problems because it’s solving the data problem, you don’t have to think about it anymore, but then the last 10%, when you have complex state management scenarios, you still have to reach out for a solution. Some people reach for Redux, some for MobX, or whatever you’re using… But I don’t think that client state management is solved for now. We’re still waiting for some silver bullet solution that’s gonna solve both the client side and the server side with fetching data with GraphQL. Anyone else wants to add something?
I just wanna add - for local state for a component it’s totally fine. A state management solution is good for maybe more complex state, as well as GraphQL is good for transportation layer, but still, if you have some kind of counter on your page, you don’t need to add this counter to your state management solution; you can just rely on local state, it’s good enough. I just wanted to add that.
A question more about new possibilities, new tools that we need… I’m thinking or asking that we have a new kind of application, an online collaboration tool, like Wiki or Google Docs, and how state management can help us to build this solution more easily than we can build it now. Each technology right now you need to synchronize state across many clients, you need to do it efficiently, easily, and you need to solve a conflict between different clients because we still have a lot of connection, and we need to solve it somehow.
As I see, people who start building these online synchronization tools, they struggle a lot to build something reliable. They spent a year to build something usable. Maybe you have comments and ideas how GraphQL, MobX, or maybe the next tool deals with that. I’m talking about mobx-state-tree solution maybe… If you can address that.
I guess I’ll give this microphone to Michel then.
Yes. When it comes to synchronizing changes, and especially rebasing and handling conflicts, there are a couple of problems. One thing that doesn’t help you is being able to time travel. I see that people often start with that, but it just doesn’t fit for multi-actors systems. So you need to be able to do either one of two things - one, you need to be able to replay your actions, so that you can distribute actions and then make sure that everybody replays them in a consistent order, so that everybody ends up in the same state. I think that’s the best solution in general.
[12:16] The second solution is to be able to generate and replay patches. That’s kind of the generalized form of actions. You’re basically recording what mutations happened, and then you’re replaying those. That also works, and it’s usually simpler to set up. For example, if you’re already using mobx-state-tree or Immer or something like that, you can get the patches; the problem with patches is that conflict resolution is harder, because you cannot really determine what the user intended to do from patches, while you can still reason about what the user intended to do if you have a description of the actions that were emitted.
In any case, I recommend if this is the core of your project and it’s really important to do it well, you need to make sure that you have an explicit piece of code in your application where actions are dispatched and are described in a serializable manner, and whether you use Redux for that or mobx-state-tree doesn’t in that sense really matter. In the end, most of the complexity comes from the fact that how you handle that conflict isn’t a problem that is solvable in an abstract way… Because what the meaning of a conflict is always depends on the meaning of your data for your application.
Some conflicts it’s fine to just elect randomly a winner. For other conflicts, you want to make sure that no decision is being made automatically by replication and that the user has to redo things or loses his actions. Answering that question depends on your problem domain… So you cannot get proper conflict handling standardized in a state management solution for that reason, but have replayable actions gets you a far way.
With that answer I can totally relate. Actually, I’ve just been at the App.js conference last week, or maybe two weeks ago, and there was a great talk by Eric Vicenti about his brand new cloud framework called Aven, which is for building web and mobile apps, and a lot of its features is essentially implementing this conflict resolution mechanism where you can think of it as Redux on a server, where you essentially store your actions, and then they are replayed on the server for the conflict resolution mechanism.
So if you are looking for a solution to that problem, or a candidate to that problem, then I would recommend you just looking at that tool, and the talk maybe, and if not the framework itself will be suitable for you, maybe just the concepts or the ideas that he presented might work for you, too.
So that’s the use case for state management that I still see these days, such as Redux or MobX, as opposed to the component state being the conflict resolution, and sort of sharing the state between different apps. And also, for example, if you want to store it on the native side of things, in React Native, that’s also useful for you to have.
I wanna add on the GraphQL side… On GraphQL, lots of things are kind of already solved if you use subscriptions, and if you have a reliable usage of subscriptions… But sometimes people overuse that; for example, if they use Apollo client and they use a subscription component as a component with a render prop they will rely just on data getting back from the server, and it will be reloaded on the page. In some instances when you have these conflicts, you will have a flash of content that you don’t need, right? So there is a pattern of using a subscription as sort of a notificator, and instead of rendering something on the page, whenever a subscription gets back to the client, you basically update Apollo Cache with the data that you have control of.
[16:04] That really connects to what you said, that by replaying things on the client, you can totally connect that to things that you said, and use a subscription as a method of notifying the client that something has changed. Then you have the ability to do whatever you want.
I was actually interested in this problem, so I was poking in the network tools for Todoist, for Notion, for Google Calendar, just to see what they’re doing. And basically, I think every one of these big companies have built their own caching client server mechanism for synchronizing the changes… So I don’t think they’re using GraphQL subscriptions. I mean, GraphQL subscriptions are a step towards the solution, but I think it’s still not a silver bullet solution for this problem.
If you look at Google Calendar, Todoist and Notion – when I tried Notion for the first time, I’m like “What the hell is going on? Probably the client state management is so complex; this cannot be solved with simple GraphQL, or Apollo Cache, or something.” So you have super-complex client state management in Notion, and every second or after every action they’re dispatching some sort of weird JSON object to the server. They’re serializing, deserializing, and then doing something on the server… But it’s still some custom mechanism, and I don’t think it’s available as a library that you can just plug in and just use whatever they’re using. You wanted to add something?
I would just add that… There is actually a library made by Andrey Sitnik. I don’t know if you heard of him; he made Logux. So the whole idea here is to operate not in JSON, not in a snapshot, but on a operation log. The tricky part of the operation log is you want to make the timestamps function between server and client in a reliable way. That is a hard problem. If we could solve that problem, we wouldn’t have conflicts at all, because we could ID every item in the log in the right way; that’s kind of an unsolvable problem, so he tried to solve it in a way - a CRDT kind of paper, so look up for CRDT. I think that’s the latest we got in the theory.
It works in 99% of the cases, he said… So check out Logux. It’s like Redux, there’s operation logs so probably it might be a solution for you, I don’t know. Reach out to Andrey; he is really pushing it forward, so he might be of help for you.
Just as a small thing, just to demonstrate why your problem is not solvable in a generic way - even if we can fix the timing and rebasing problem, the problem is there’s semantic meaning to all your data. To give a very simple example - suppose you have two users seeing the same variable, X. Both of them see the value of X is 1. And behind it you put a button that increases the number by 1. Now both see 1, and both press the button simultaneously. Then the question is what should the end results be that both users see? Should it be 2, because they both increment from 1 to 2, or should it be 3, because both incremented?
The answer to that question depends on what the number means. If the number means how many people did visit this space, or something, then the answer should be three, because both users visited the place. But if the meaning of the number is how many attendees are allowed at the conference, then both of them intended to set it to 2, because they wanted two seats to be available, or something.
So the meaning of an increment doesn’t depend on how you solve the conflict, it depends on what the action means from a domain perspective, and that is the reason why the problem is not generically solvable, because you want to handle conflicts in a different way, depending on the meaning of your data.
Great question. That was a very good discussion.
I have more questions, but I’m curious before I do, anyone had a really good question come on via the Advice Lounge that you think would be good to get more perspectives on?
Well, I had a really interesting question regarding the N+1 problem in GraphQL and how it’s solved. I am working at Hasura as a developer advocate, and some people ask me about how it’s solved and what are the challenges for the N+1 problem. Facebook uses a data loader, some solutions use different solutions, too. The idea is for every type you have a resolver that will fetch the data, so you’ll get the N+1 SQL statements if you’re connected to a database.
The question was how we solve it at Hasura. Basically, it’s a generic solution that you can use not only by using Hasura engine, but implementing your own thing… If you manage to comply all your resolvers to some kind of one SQL statement, that you will solve this problem.
I’m not sure how many sessions you already had, because I just arrived one hour ago, and I only had one, so… [laughs] So the question was “How many of you are writing React Native here?” Okay. And the rest, I assume is doing React, right? Okay. And are you interested in writing React Native, or not at all? Okay, so the question you might find useful was “How can I get started with React Native and whether that requires a lot of native knowledge?” Basically, the answer was that you can try with Expo if you don’t want to write native code… But you know, the second answer to that question was that the native knowledge you need in order to write React Native is not really that scary; it’s all about knowing how the project looks like and how you can start it. Problems will be when you want to release it, but trust me, when you get to the release step, you will be a great native developer, so don’t get scared about that at the beginning.
Okay. Question from the audience.
Hi. My name is Isha, software developer. I’m a .NET developer, and I am very familiar with Xamarin when I develop native apps. What is now the main advantage when I move to React Native? And I have good React skills also.
[24:17] That’s a good question. I’ll try to answer as best I can, though I never used Xamarin and I only have conceptual knowledge about that… But there is a great friend of mine that I promised I’m gonna reach out to - his name is [unintelligible 00:24:28.26] Speaking from his past employer, I think he knows a bit of Xamarin, so he might tell you a bit more about that…
Yeah, so I might be wrong, but what I’ve seen - and correct me if I’m wrong - is Xamarin does have the same robust solution for GraphQL that React Native has, as well as Flutter. And GraphQL is changing a lot in the mobile ecosystem… And it came from the need to do less requests to the server or the lower end devices to get the traffic faster, and to get all the data that we need. I don’t see it available in Xamarin, nor Flutter, and this is one of the additional pros towards React Native.
I think also one last thing to mention is the knowledge is very transferable. If you already have a web app, and if you have a team working with React, you can easily transfer them to work on React Native, and even share components. I’ve seen apps who have – some GitHub client had like 80% of code reusability between web and two native clients for Android and iOS. So I think you can also share a lot of things, and if you already have knowledge of React and of GraphQL with Apollo, you can just transfer it easily to React Native.
You have the advantage of having access to this entire ecosystem that’s constantly – I think it’s evolving more than the other ones. I don’t wanna bash on the other ones, but a lot of innovation is happening right now in this one, so that’s also a big advantage.
[28:06] I’m not a native developer, but I can sit down and give a React Native workshop at a company for a week, and I wasn’t a React Native developer. I just sat down, looked at the docs, and I’m like “Okay, this is just React, but for native.” So that’s a big advantage.
That sounds like a topic for your next vlog, right?
But that’s the thing, React Native’s long-term goal is to be less native. When I had a chat with the React and React Native team back at the React conf, the general feeling was that we should stop speaking of React Native as a separate thing, because React Native essentially could be just React, but rendered on different platforms, so there’s no reason for differentiating these… And the long-term goal we have with React Native I believe is to decrease the amount of native knowledge you need to know, and that’s also what we are trying to accomplish with the CLI and the tools that we build around React Native, to make your experience working with dependencies and native code as smooth as possible. We are still somewhere in the middle of our road, but we know where we’re headed, so this should be improving with every month.
It’s unrelated to the technology choice, but more on an architectural level. I think this blurring the line between native and non-native - it’s really important to keep in mind the architectural choices… But the things I talked today about primitives - I think it’s even more important to think about UI elements as primitives; you’re not going to use HTML primitives for example if it’s web, trying to put them in abstracted primitives… Because by doing so early, you could save a lot of time when you start thinking about “Okay, now I want to build a native app, using the same buttons, inputs etc”, because you can abstract the rendering target completely… So yeah, I think it’s important to keep this in mind, architecting the app, the whole user interface.
Alright. We are getting close to the end, we probably have time for one more question. We have a question coming in from the audience…
A question regarding React Native… Recently we’ve seen some articles that some companies are leaving React Native, and want to write their applications with React Native. The question - what do you think, is this still around, is it still reasonable to start a new application with React Native, or better to hire real native guys who will write the real native application for iOS and Android? What do you think?
I have a great example how React Native can be better than native apps… I personally, with a few of my friends my company, we built a media player for singers… And fun fact is that the company came to us, having already built the mobile app by one of the best agencies in Europe, and they were struggling with the performance. We were able to outperform the performance of the native app with React Native two years ago, without all the great things that we have right now. So it is totally doable, and actually the reason their approach was slow was that it was all imperative, so the declarative nature of React Native sort of won.
Regarding your question about companies leaving - you know, it’s always gonna happen, because React Native itself is not a silver bullet, and it’s getting great adoption at different businesses, and they are trying React Native to see if it fits their business goals and architecture.
[32:01] One of the approaches with React Native - there’s the brown field approach, where you integrate React Native into existing infrastructure, and the green field one, where you start from scratch. So it can always happen that when you start integrating React Native into a native app, it will not work for you. For Airbnb it didn’t work out in the long-term, just because of the trade-offs were not good for them, and I think the article was pretty explicit about that… But there are hundreds of companies using React Native, and actually thousands of apps in the app store. I’m not sure if I can disclose the number and how it was mined, but there’s a lot of React Native applications out there, and they are in a pretty good shape.
Last year when we were talking about React Native, there were a lot of people asking me and other contributors “How is React Native looking like?”, whether it’s gonna be the thing, or it’s gonna sort of vanish… And the general feeling inside the community was that we could do better, and everybody was slowing getting out of ideas… But things dramatically improved since then, and over the last year things changed from being not so good to being amazing. We have a lot of great development going on, such as the new re-architecture, that will allow great things to happen, especially for the native developers. So a lot of these advantages that these companies are talking about right now will be totally gone in a matter of a few months…
So I’d say there’s a really bright future ahead, in front of React Native. I’m saying that after exploring Flutter and other technologies for mobile alternatives… I’m still thinking that React Native is the best technology right now on the market for that particular cross-platform solution. I checked the others, and speaking of trade-offs, I think it’s just the best one, unless you don’t need a cross-platform app; if you are building a game, probably just build a native app. That’s not the failure of React Native, it’s just for that particular app you just need native code.
I know you work with React Native a lot, that’s basically your job, but what I wanna mention and what you’re forgetting is Facebook this year is forming the Avengers Initiative for Fixing React Native; they’re forming this team who’s sitting down and properly addressing all the problems that React Native has. When I saw that GitHub issue about “Hey, community, what kind of problems do you have?” “Here’s like 1,000 problems that we have, here’s how we’re gonna address them.” So I think now they’re gonna double down on fixing and making it stable, and I think they’re just getting started with React Native, and more and more companies are gonna adopt it, because now finally they’re properly sitting down and putting more engineering effort into actually working on React Native… So I think it’s just getting started.
Yes. I know that we are running out of time, but I just wanted to mention a couple things real quick. Kitze, that’s a very important thing you said; I just got too much technically into that matter… Last year the React Native team was getting smaller, there were a lot of people leaving, and this year it’s growing super-quick. So many great developers are joining the team; it’s just getting bigger, and you can see that by the contributions that happen. We had the London triage between Facebook and contributors from the community. That was the first hackathon ever we got together, and there’s already one planned to happen later this year… So the collaboration between Facebook and the community is getting better, and that’s the most important thing… Because historically, that was the thing that wasn’t that good, and now it’s improving. The more we keep being synced with Facebook, and the more we work together on fixing issues and improving the framework towards the direction we all want to use it, then it’s gonna be good.
So there’s this React Native community organization on GitHub, check it out. There’s a lot of information about what’s happening in React Native, where we are headed; if you want to help, that’s the place to check out. If there’s information you probably want to ask but we don’t have time, you can find it there. Thank you.
[36:01] We do have to wrap up, it is now lunch time, but let’s get a hand for this panel, huh? [applause] And if you like listening to brilliant minds like this and you like picking their brains - you can’t go to a conference every week, but the podcast publishes every week, and we do a live episode, we stream it live; you can pick the panelists’ brains using Slack rather than in-person. Here in Europe I guess it would be in the evenings; it goes live on Thursdays 1 Eastern U.S., which I think is 10 o’clock here, or 9 o’clock… I don’t know. In the evening here.
So go to changelog.com/jsparty and you can check it out. We’re available on all your podcast applications, whatever you might like, and you can get this level of thought and energy and excitement every week. Thank you so much!
Our transcripts are open source on GitHub. Improvements are welcome. 💚