DEV Community

loading...
Cover image for Simplifying your application state management with Recoil
Webiny

Simplifying your application state management with Recoil

brunozoric profile image Bruno Zorić Originally published at webiny.com ・4 min read

In Webiny we have the Page Builder Application that was built with help of redux as global state management. We decided to switch our Page Builder to Recoil due to redux being hard to maintain and debug. But before we dive into how we did it, what were the issues and how we managed to make everything work with our code structure, a bit info about ...

Recoil

It is a, fairly new, library for managing global state - like redux. It is being developed by people at Facebook and it is still in an experimental state, so you can expect things will change.

Introduction

A recoil state is contained within an atom. The official description says an atom is “a representation of the state”. You can have multiple atoms, to split state, e.g. page, content, UI, etc., which helps when structuring the actual state. It can lead to some problems though, but we will come to that later.

Recoil is used via hooks, so you can not use it in your class components. If you would like to use Recoil, and you have class components, you need to wrap your class component in a function one and pass the Recoil state and state set function.

Basic Recoil API info

Atom

“An atom represents a state in Recoil”, says the official documentation about it. Look at it as part of the global state object from redux. Of course, you can put everything in a single atom, but we reckon that is not the intended use. The main properties you need when instantiating an atom are key and default, where the key is a unique string that identifies an atom internally in Recoil and default is the initial value of the state. You can create an atom without a default value, of course, just try not to. Read more...

Selector

“Selectors represent a function, or derived state in Recoil”, as it states in the official documentation. When you are creating the selector, you need to define the key and get properties, where the key is a unique string that identifies the selector internally and get is a function that returns a value (it can be an async function as well). We explain that more later on. Read more...

Selector family

This function is used to read the state with help of a passed param. Basically, you can pass it an id and return only the part of the state based on that value. When you are creating the selectorFamily you need to define the key and get properties, where the key is a unique string that identifies the selector family internally in Recoil and get is a function that accepts an argument which you passed into selectorFamily, and it returns a function that is exactly the same as get in the plain selector. You can use the sent value to search the state or do whatever you need to do. Read more...

useRecoilState(atom | selector)

A hook that returns a tuple of current atom, or selector, value and a setter function for that atom or selector, as built-in React’s useState. Note that if you are calling this hook with a selector variable, it must be a writable selector - have set property defined. Read more...

useRecoilValue(atom | selector)

A hook that returns the current atom or selector value. This hook is intended to use when you only need to read the state, not write to it. Read more...

useSetRecoilState(atom | selector)

A hook that returns a setter function for a given atom or selector. Be aware that if you are using the selector must be writable to be able to use this hook. Also, this hook will not subscribe to the component to re-render when the value changes. Read more...

useResetRecoilState(atom)

A hook that will reset the state to the default value given when creating the atom. As the useSetRecoilState, this hook will not subscribe the component to re-render when the value changes. Read more...

Starting with Recoil

1. Install it via package manager:

yarn add recoil or npm install recoil
Enter fullscreen mode Exit fullscreen mode

2. Wrap your code in RecoilRoot component:

const YouAppCodeWrap = () => {
  return (
    <RecoilRoot>
      <YourAppCode />
    </RecoilRoot>
  );
};
Enter fullscreen mode Exit fullscreen mode

3. Create an atom:

const exampleAtom = atom({
  key: "example",
  default: false,
});
Enter fullscreen mode Exit fullscreen mode

4. Use it:

const YourAppCode = () => {
  const [exampleValue, setExampleValue] = useRecoilState(exampleAtom);
  return <Button onClick={() => setExampleValue(!exampleValue)} active={exampleValue} />;
};
Enter fullscreen mode Exit fullscreen mode

What's next? ⤵️

Switching code from redux to Recoil

Creating selectors

Creating selector families

But Recoil is missing something ...

Follow the article here


Thanks for reading this blog! My name is Bruno, and I work as a software engineer at Webiny. If you have any questions, comments, or just wanna say hi, feel free to reach out to me via Twitter.

Discussion (0)

pic
Editor guide