DEV Community

Cover image for Recoil  - Ideal React State Management Library?
Alex Zavalii
Alex Zavalii

Posted on • Updated on

Recoil - Ideal React State Management Library?

In May 2020, Dave McCabe gave an interesting talk about the new state management library called Recoil. The video clicked immediately with me and inspired to write this article. Recoil is the missing puzzle piece for state management in React.

So why do we need another global state management library?

The reason we have so many different libraries of managing state in React, is that there is no oficial one yet.

Is Recoil an official one? No it is not.

But what is particularly different from the rest, is that Recoil is specifically designed for React and feels like React.

What's wrong with Redux?

Redux is by far the most popular library for managing state out there, but it does not come without drawbacks. Redux same as Recoil was designed for performant, predictable and debuggable updates of shared state. But let's take a look at what is not so great in Redux:

  • Ridiculous learning curve.
    Some of you might not agree with the learning curve, but to me, after I got more or less comfortable with React, I really struggled to understand Redux. Like, how to structure the project? how to store the state? where should my business logic go? Redux documentation is overwhelming, and I am sure it has all the answers to these questions, but to really nail them down, it would take you quite a bit of time.

  • Boilerplate – reducers, actions, connectors.
    Not many would disagree that Redux has too much boilerplate. If you are dealing with async data or caching computed selector values, you need to install third-party libraries solutions and add even more boilerplate. Additional code comes with the cost of having more bugs.

  • Restructuring of Business logic
    I think a Redux way of splitting business logic from the components, is not going very well with the React component based approach. Introducing Redux will require you to redesign the structure of your project.

  • No “concurrent mode” support YET.
    React concurrent mode is very soon to be released. "Concurrent mode" is fixing fundamental limitation by making rendering interruptible. Not supporting "concurrent mode" will be a major drawback of the library. As of now, React-Redux does not support it, but it is planning to introduce useMutableSource hook, that will make it compatible with "Concurrent Mode".

What's wrong with Context API?

Context API is an utility coming from React core, specifically designed for solving the prop drilling problem. As opposed to Redux, it is good to be used for low-frequency updates, such as theme or locale. But because of Redux drawbacks, Context API often becomes overused.
There are some drawbacks once we start using Context as a state management tool

  • Unpredictable and not performant updates.
    Because of how it was designed, context lets you store only one single value per Provider. If you move your global store in the value of the Provider, you will be losing out on performance. When a React <Context.Provider> gets a new value, all the components that consume that value are updated and have to render, even if a component only cares about part of the state.

  • No way of creating context dynamically.
    Imagine if you have a list of items that you dynamically add or remove, and each item has to have its own context provider for isolation or for performance reasons.
    Dynamically inserting context
    Introducing another item would require placing another Context Provider at the top of the tree, which would cause the whole tree to unmount and mount again.

  • Context Hell
    Context API definitely has much less boilerplate then redux, but if you start adding them more and more, your react tree would look something like this.
    Context Hell

  • No code split support
    Because Context API introduces coupling between the roots of the tree and leaves of the tree, code splitting becomes nontrivial.

So What is Recoil?

  • Very easy to learn, simple API.
    To get through basic API you would literally need 5 minutes. Here is a nice free egghead tutorial by Tomasz Łakomy.
    But also please check the docs.

  • Minimal boilerplate and reactish approach.
    Recoil does have almost zero boilerplate, and it looks and feels very like just using simple useState from React. You only need to wrap your app once in <RecoilRoot>, and you can have as many independent global states as you like.

  • Performant granular updates.
    Recoil allows you to connect to the exact piece of state, which is a huge performance benefit. By creating an atom you add a new global state, by creating a selector you are adding a function that returns data derived from the given set of dependency values. Both atom and selector can be subscribable and writable.

  • Dynamically created state
    Recoil allows you to create dynamic global states, by using atomFamily and selectorFamily. Both atomFamily and selectorFamily accept an id, which will dynamically create a state or a selector function.

const itemWithId = atomFamily({
  key: 'item',
  default: ...
});

 useRecoilState(itemWithId(id))
Enter fullscreen mode Exit fullscreen mode
  • Async Support. Recoil comes with async support without any third-party libraries. Derived data can be synchronous or asynchronous without modifying the components that use it.
const fetchUserDetails = selector({
  key: "oooo",
  get: async () => {
    try {
      return await fetchUsers(url);
    } catch (error) {
      throw error;
    }
  }
});
Enter fullscreen mode Exit fullscreen mode
  • No impact on code-splitting.
    Unlike Redux or ContextAPI, Recoil state is not stored globally anywhere, the state definition is incremental and distributed, which makes code-splitting achievable out of the box.

  • Concurrent mode support.
    As opposed to other state management libraries, Recoil is built on React primitives, it is using react state under the hood. For this reason, Recoil is not usable outside of React, but it works very well within React. As of the time of writing this article, Recoil does not have the "concurrent mode" support yet but is planning to achieve it with the use of useMutableSource hook in the near future.

Conclusion

Of course, Recoil is not ideal and there are still many unknowns. But what I like most about it, is that using Recoil feels so much familiar than existing state management libraries out there.

Currently, the library is in a very early stage, but I am sure it has enough to get you excited. Official Get Started

Thanks for reading my thoughts on Recoil. This is my first article and I would be interested to hear your feedback.

Top comments (23)

Collapse
 
markerikson profile image
Mark Erikson • Edited

Hi, I'm a Redux maintainer. A few quick notes:

  • To my knowledge, Recoil is not currently Concurrent Mode compatible. David McCabe made a couple comments on Reddit about investigating options like the upcoming useMutableSource hook, but I don't have a link to that discussion atm.
  • React-Redux will also eventually be using that useMutableSource hook when it's out, likely in a React-Redux v8 release. This won't make it "fully CM compatible", but it will likely be sufficient to allow React-Redux to work in a CM-configured React app
  • The Redux code splitting recipe you pointed to basically boils down to re-generating the root reducer by calling combineReducers again, and then passing that to store.replaceReducer()
  • I'm currently working on a major set of updates to the Redux core docs, including new tutorials and reorganized content. That said, you mentioned things like "where does my business logic go?", and we specifically already answer questions like that in the Redux FAQ. The new Redux Style Guide page also gives specific guidance on recommended patterns and best practices.
  • Finally, please check out our official Redux Toolkit package, which is specifically designed to simplify most common Redux use cases.

Note that I'm not saying anything negative about Recoil here. While I haven't tried it out, it definitely looks interesting. I'm just saying that you might want to reconsider the list of negatives you listed for Redux :)

Collapse
 
alexandrzavalii profile image
Alex Zavalii

Thank you Mark! I will follow your notes.

Collapse
 
birdtho profile image
Christopher Thomas

Go try it out.

Collapse
 
vacom profile image
Vitor Amaral

Recoil is very simple to use and feels like it is included in the React core. Oficial or not it is made by Facebook I think that gives some proximity to React. Recoil has a lot of potential, let's help it grow. Nice article Alex. Cheers.

Collapse
 
brianmcbride profile image
Brian McBride

Keep in mind that the "React Core" isn't a very complicated and other libraries work just as fine.
I suggest you take a look at Hookstate.js. It is basically the same thing as Recoil, but I'd go as far to say it is even easier to use.

The problem with Facebook koolaid (realize that I still pick React for my front end work, although I am considering Preact these days), is that Facebook engineers are people too. In fact, they are people who passed an interview in Silicon Valley that is known to be sexist, racist, and agest (sadly). What I am getting to is that these tech giants don't have the best of the best, they have the best applicant at the time who passed their biased culture screening.

My point is here, although Recoil has many aspects that I prefer - why didn't Facebook just adopt an existing library? We already have this solution out there. Instead, there is an alpha/beta codebase with less features that the entire community is making hype about. It doesn't mean it will get better development either, as most developers just use libs like redux and rarely bother to actually look at the source to see what it actually does, much less try and contribute to it.

Collapse
 
alexandrzavalii profile image
Alex Zavalii

Thanks Victor!

Collapse
 
thisdotmedia_staff profile image
This Dot Media

Awesome article Alex!

Collapse
 
alexandrzavalii profile image
Alex Zavalii

Thank you!

Collapse
 
thisdotmedia_staff profile image
This Dot Media

Np 😊

Collapse
 
kawashita86 profile image
kawashita86 • Edited

Just as a matter of taste, i love using redux as It allows me to split my presentational layer from the state/remote data action one. Using redux+rx/js further separate those concept having actions behaviour in a different folder from actions and reducers. It's clean, easily testable and on bigger projects i found myself to touch less files than on project where i use hooks or others libraries. Said that recoil Is interesting and i will follow its evolution closely as It brings really interesting concepts for high-performance heavy-duty UI

Collapse
 
brianmcbride profile image
Brian McBride • Edited

I dunno. If this wasn't a library from a Facebook guy, we probably would be ignoring it. I mean, we have similar code out there. Mobx is one (of many).

No offense to Mark Erikson here in this thread - I can't stand Redux. I love the concepts, the boilerpate though... :) In my projects, I tend to use an Observable library (I have my own spin from RxJS, I've used Mobx, and lately the Apollo client a lot)

So when I see Recoil, I don't see a lot of new, just different. I am not sure it is offering a lot new to the landscape other than splitting focus again.

For me, that's the big issue. If you want to follow an observable pattern, use Observables and help improve on the existing foundations. Maybe I am missing something that is so special about this lib, but the only thing I really see is that it's an internal Facebook library and suddenly everyone is wondering if it is going to become the "official" React tool.

Here is something that I like to share with my teams - is ReactJS going to be the last front end tool we will use? There is something that bugs me that we keep pulling things off the shelf that are not View components but only work with React. When I use GraphQL/Apollo, I know that I can take my queries to VueJS or just to pure web components. I can keep my "engine" code reusable across "view" libraries. Even within React, this can sometimes mean easier upgrades too. We already see this with Redux, Mobx, etc... where I can take any of these state engines and drop them into any UI project (including React Native) and go.

Collapse
 
koistya profile image
Konstantin Tarkus • Edited

Taking the basic use case scenario - UI theme switching implemented using React's useState(), useEffect() vs Recoil. The Recoil implementation looks so much smoother:

Implementing UI theme switching (a.k.a. Dark Mode) using Recoil

Collapse
 
antonmelnyk profile image
Anton Melnyk • Edited

API isn't simpler then Redux at all. No devtools, no clean update cycle, logic inside UI layer isn't a good thing and that is main advantage of Redux, which is pure functions that change state and contain all logic.

Recoil seems like just another overhyped state management tool, while good ol' dog Redux is a proven and solid solution with a great ecosystem.

Collapse
 
creotip profile image
Ruslan Elishaev

recoil + redux devtools
github.com/creotip/recoil-gear

Collapse
 
basit_raza profile image
Basit Raza

Redux is also a good choice, as time passes new technologies take the place of old ones i personally feel implementing redux Restructuring of Business logic, but it work as expected. I just read about Recoil it seem interesting and especially it simple, i'm gonna try it soon.

Collapse
 
pavermakov profile image
Pavel Ermakov

Great article!

Does recoil have some sort of a devtools extension?

Collapse
 
alexandrzavalii profile image
Alex Zavalii

Thats a great question. I think there will be one. Just saw this tweet.
twitter.com/jaredpalmer/status/126...

Collapse
 
creotip profile image
Ruslan Elishaev

recoil + redux devtools
github.com/creotip/recoil-gear

Collapse
 
birdtho profile image
Christopher Thomas

Recoil is really cool. Not only is it good for maintaining different chunks of State here and there, but you can also build hooks around it that have the same data and update the same data no matter where you are in the app. You can use the same hook you wrote to refer to the same data in multiple different components because you're basing that hook off of recoil state.

I get some things like lists of tags or videos, etc and store them in hooks using methods to modify or refresh the list, backed by recoil atoms.