This, in contrast to my previous pieces, will be a more opinion based article. So, dear reader, treat everything here with a grain of salt - it's j...
For further actions, you may consider blocking this person and/or reporting abuse
"there is no easy way in React to share state instances between components"
React Context lets you easily share state in all components, doesn't it? This is a common solution to state management that uses built-in React features.
No - it does not let you easily share state in all components. It let's you easily share state in all components that are descendents of the context provider.
Personally, I love context. It allows me to think of controllers as components. I don't have to deal with the boilerplate of redux and I don't have to deal with the magic of mobx.
But, if I'm on a team of developers that have various levels of experience in react, I would almost always go for redux as long as an experienced senior is driving the redux bus. If everybody on the team is experienced seniors in react, then context is a-ok by me.
Having to be a descendant of a context provider isn't a huge limitation or drawback for context. But I'm sure there are some scenarios I could be missing where that's an issue.
I didn't say, nor imply, it was a drawback. It's not. It's actually a huge feature. React is still, even after several years of composable UI, a "new way of doing things" to a lot of devs and it's hard (or impossible) to grok it all at the outset. To say something like "context lets you share state across all components" is a confusing statement to the ones who haven't made their own mental models yet when they try it and it fails, or they nest context providers without realizing it and end up in a really uncomfortable state because they can't connect "context = global shared state" with what they're seeing with they're own eyes.
Ah I gotcha. I read your original comment wrong. Thanks for clearing that up for other readers 👍
I made an account just to comment on this.
The whole time reading this article I was thinking "WHAT ABOUT USECONTEXT????"
This is the third article I've read today that discussed the struggle of shared state in react, and didn't mention the useContext hook. Is there something I'm missing?
I dont do huge apps, but Mobx worked really well and I haven't run into any of the mentioned issues. I split state into multiple Mobx stores, organized hierarchically. So only RootStore usually gets pushed through provider and other stores are accessible through it. Also parent store is referenced by child store so you can go up the hierarchy too. Basically, its what Mobx docs suggest: mobx.js.org/best/store.html
I must say I also haven't had any unexpected behavior. Quite oposite. "Scratching my head" with React usually was about why some component was rerendering more than once, or even twice. I'm really careful about optimization there. Hate to see rendering time wasted. I find that goes away with Mobx. React state, Memo, and other ways to fight it are in my opinion much more complex thatn Mobx. In Mobx, all you have to remember basically is "dereference values as late as possible" (one point from Mobx docs: mobx.js.org/best/pitfalls.html)
Hey Mirko. Thanks for commenting.
Maybe that wasn't entirely clear in the article, but I DO consider Mobx superior to Redux in most of use cases.
I didn't have "scratch my head" moments too often when developing an app, but I still felt that I am not fully in control of the framework.
This article wasn't meant to bash Mobx (or even Redux). If it works well for you, by all means continue to use it.
No, no, I haven't foind your article to bash Mobx. Just focussed on Mobx part of it, trying to find myself there, but didnt :). And wanted to share.
Mobx is a "magic black box" often, but I got so used to it that it doesn't serve me any surprises.
Fair enough!
Glad it works for you. Thanks for the comment. :)
I read the whole article, it made a lot of sense to me as we did face the same issues with redux and simiarly mobx. Good job!
For our app, which was made via knockoutJS, have very similar concept to mobx, namely the pub-sub pattern and the computed functions. Just like you said, a lot of complexity comes from asynchronous functions coupled with mobx. So I am wondering what do you think if we structure the app in the way that we will have components handle the service calling, not mobx. This way we take out the step that causes complexity ?
I think you may end up with some problem later unless the app is very small. If you put the fetch logic in the component it is hard to share if needed by another component (that is, another component must be able to fetch this data and update the store). If you then move it outside of the component into a helper you are very close to a thunk or action any way but it is outside the components and the store and therefore a bit harder to find. One nice thing with mobx is that almost everything about state and actions can be found in the store.
It could also make writing tests harder. When everything is in a mobx store you can write tests for it. If you split it into a store, some helper and a component you have to test them all combined to know that the application works.
I agree with your observations, namely that if everything's inside the store then you'd have a centralized place for everything. However, I think that's exactly the drawback of the. We had a relatively small app that used redux and had all types of data, global state and service responses, stored in there.
It quickly became a nightmare when there are scaffolding after scaffolding for getting stuffs, which was hard to explain to our team lead who had no hand in building it. It felt as if walking in a labyrinth inside the store. If everything was separated completely, store only has global state, service layer is the controller, cache layer is another, then it would be much clearer.
as for writing tests, you may very well be correct, but I am too newbie at test-writing to comment on :P
Hey Kevin, thanks for the reply.
I like your point about async stuff bringing a lot of trouble to Mobx.
Moving async stuff to components definitely might work nicely. My only fear would be only that it would again turn into "Redux-esque" architecture, where whenever somebody new comes to the project, you have to explain to them "oh, we don't put async stuff in Mobx stores, we put it in components, blablabla...".
But maybe that's not a huge issue and if everyone in the team is on the same page, I think it would be completely fine to try that approach.
awesome thanks!
What do you think about Recoil? Recoil enabled me to manage states in a similar way to React. It requires much less boilerplate code than Redux, and it also integrates well with React.Suspense for asynchronous code.
I haven't really used MobX before so I can't speak about it though.
Hey Makoto.
Never used Recoil, in fact never seen anyone using it.
But you got my interest, I will definitely check it out. Thanks!
I'm a newbie but have been using Recoil on a multi-screen app. Works great for me so far and fairly easy. Maybe too easy.
I really like the idea of a
useSharedState
concept, and I recently attempted that and created a very small library for it in: github.com/sammysaglam/react-stateyI don't any reason why something like this wouldn't be great & simple! And to address asynchronous behavior, I call
setState
in auseEffect
, which I think is also quite easy to handle & read.Thank you for writing this. I finally understand the core differences between Redux and MobX.
Regarding
...have you seen ReactQuery or Vercel's SWR?
They're two very similar libraries. I think you'll like them.
I mention them in some of my posts.
Thanks again!
Dude, try "react easy state" it's the way to joy and peace.
Will check it out, thanks!
In additional to the docs here github.com/RisingStack/react-easy-...
this is an interesting read to blog.risingstack.com/reinventing-h...