Why I stopped using Redux and Used Recoil Instead
Tags: javascript, react, redux, recoil
Published: 2021-03-31 05:27:18

###What's wrong with Redux?
Redux is not perfect, but it is by far the most popular state management library used with React. Let's look at what's not so great in redux:

* Giant Learning Curve
There are so many concepts to learn like actions, action creator, reducers... and when we throw class based and functional components in the mix along with a different way of dispatching while using thunk etc, It can really scare a beginner

* Huge Amount of Boilerplate
Everytime we want to setup a redux app, we have to create reducers, combine them, create a store, add middleware, link to devtools, computed values etc. We need to add so many 3rd party libraries which have a config of their own and introduce another layer of complexity.

* Restructuring Folder Structure
The react component based approach does not align itself very well with the redux way of splitting business logic. If we want to introduce redux into an existing react app, then we need to change the file structure and a lot of code has to be changed.

###Context API
The context API is not really a solution for this. It solves the prop drilling problem... not global application state. You cannot pass data across siblings using context. The child will have to update the parent which will update another child(the sibling).

###Terminology with Recoil
Unlike redux where we have so many concepts to understand... there are only a few in Recoil

#####Atom
This is the easiest part of the terminology.... an atom is basically a piece of state

#####Selector
A piece of state that is calculated on the basis of another atom(s) or selector(s)


###Recoil
Let's begin by installing recoil

```zsh
npm i recoil
```

Whenever we want to use recoil, we need to have the `RecoilRoot` component somewhere in our component tree.


```js
import React from 'react';
import {RecoilRoot} from 'root';

export default function App() {
  return (
    <RecoilRoot>
      <h1>Recoil Demo</h1>
    </RecoilRoot>
  )
}
```

When we want to create an `atom`, we use the `atom function`.

```js
import React from 'react';
import { RecoilRoot, atom } from 'recoil';

const counter = atom({
  key: "counter",
  default: "0"
});

export default function App() {
  return (
    <RecoilRoot>
      <h1>Recoil Demo</h1>
    </RecoilRoot>
  )
}
```

Each `atom()` takes in 2 fields:

1. `Key`
The key is the name our atom. It must be unique in our application and we use it to get the value of the atom.


2. `Default`
The `default` is the initial value of our atom

We've created an atom but we'll also need to access it. We use the `useRecoilState` hook


```js
import React from 'react';
import {RecoilRoot, useRecoilState, atom} from 'root';

const counter = atom({
  key: "counter",
  default: "0"
});

export default function App() {
  const [number, setNumber] = useRecoilState(counter);

  return (
    <RecoilRoot>
      <h1>Recoil Demo</h1>
      <button onClick={() => setNumber(number + 1)}>{number}</button>
    </RecoilRoot>
  )
}
```

We pass in the `counter` atom to the `useRecoilState`. Very similar to the `useState` hook in react, `useRecoilState` also returns the value of the state and a function to set the state.

I've added a simple button that shows the value of `number`. When we click on it, we increment the `number` state using the `setNumber()` function.

This atom can be used in another component too. In case we only want to access the value of the `number` atom, we can use the `useRecoilHook`.

```js
function Display() {
  const number = useRecoilValue(counter);
  return <p>{number}</p>
}
```


###Derived State
Let's begin by understanding what derived state actually is. It's a piece of state that is calculated on the basis of another state.

It's very easy to do this in recoil. We can use the `selector()` function. A selector is a pure function that takes in atoms or other selectors. We'll cube the value of our counter.

```jsx
const cubed = selector({
  key: "cube",
  get: ({ get }) => get(counter) ** 3
})
```

The `key` field is nothing new... it specifies the name of our state, as I mentioned earlier, It must always be unique. The `get` field is where things get interesting. I agree it the syntax is complicated but this gives us a lot of power and expands the possibilities. Whenever an atom which the selector uses changes, the selector is recalculated Let's go through the code line by line.


We are giving a function to the `get` field. Recoil passes an object into that, from this object we are destructuring the `get` field. The `get` field is a function that allows use to pass in the `key` of an atom or selector and access it's value. Then we are raising it to the power of `3`. Here we have used only one `atom` but we can use multiple atoms for computations. 


```js
import {selector} from 'recoil';

const cubed = selector({
  key: "totalPrice",
  get: ({ get }) => {
    get(numState) ** 3
  }
})
```

###Folder Structure
Let's say the we have 2 broad categories of state in our app: users and todos. All the atoms go in `/atoms` and the selectors go in `/selectors`. The atoms related to users will go in `/atoms/users.js`, the atoms related to todos will go in `/atoms/todos.js` and so on.


That's all for now, thank you for reading until here. I hope you guys liked this post, if you did please like the post and follow me. Bye 👋