15

ReactJS: State Persistence Using Recoil

 2 years ago
source link: https://dev.to/joiellantero/reactjs-state-persistence-using-react-recoil-29oc
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Recoil is an open-source experimental state management library by Facebook. It's one of the many libraries that makes managing states easier like persisting the theme state of your website. Other examples of such libraries are Xstate, Redux, Zustand, and Jotai.

Getting Started

In your project, install Recoil using the npm command below:

npm install recoil

Enter fullscreen mode

Exit fullscreen mode

or if you're using yarn:

yarn add recoil

Enter fullscreen mode

Exit fullscreen mode

You can view more installation guides in the documentation here.

Next, we need to add Recoil to our index.js so that we can use it everywhere in our project.

...
import { RecoilRoot } from "recoil";

ReactDOM.render(
  ...
    <RecoilRoot>
        <AppRoutes />
    </RecoilRoot>
  ...
  document.getElementById('root')
);

Enter fullscreen mode

Exit fullscreen mode

Creating an atom

Atoms contain the source of truth for our application state and below is an example of creating an atom.

export const darkModeState = atom({
  key: 'darkMode',
  default: false,
});

Enter fullscreen mode

Exit fullscreen mode

For use cases like this, I like to put my atoms inside a globalState.js file inside the shared folder of my project. This is because many components will share this atom. Moreover, inside the atom that I made is a unique key and a default value. An atom key is a serializable value that labels the atom and it's useful especially when we want to persist our state. On the other hand, the default value is the default state of the atom.

Using the atom in your component is almost similar to useState hooks:

const [isDarkModeEnabled, setIsDarkModeEnabled] = useRecoilState(darkModeState);

Enter fullscreen mode

Exit fullscreen mode

Instead of useState, we use useRecoilState and instead of passing the default state, e.g., false, we pass in our atom, i.e., darkModeState.

When we don't need to change the state of the atom and only need access to its value, we can simple do this:

const isDarkModeEnabled = useRecoilValue(darkModeState);

Enter fullscreen mode

Exit fullscreen mode

Saving the state to local storage

There are use cases when we want to keep states like the preferred theme to the website visitor's browser local storage. This helps returning visitors to keep their preferred settings that they set during their previous visit.

Below is an example of using Recoil to persist the theme of a website.

const localPersist = ({onSet, setSelf, node}) => {
  const storedData = localStorage.getItem(node.key)
  if (storedData != null){
    setSelf(JSON.parse(storedData))
  }
  onSet((newData, __, isReset) => {
    isReset
      ? localStorage.removeItem(node.key)
      : localStorage.setItem(node.key, JSON.stringify(newData));
  })
}

export const darkModeState = atom({
  key: 'darkMode',
  default: false,
  effects_UNSTABLE: [localPersist]
});

Enter fullscreen mode

Exit fullscreen mode

Notice the effects_UNSTABLE parameter that I added to my atom. This doesn't mean that there's a bug or something rather it refers to the API as it might change in the future since Recoil is still evolving.

Furthermore, the localPersist function can be called by any atom. In other words, if you need a state to persist, you can just call the function to get, remove, or save the data to your local storage. Besides boolean values, the function also works for other data types like strings, objects and arrays:

export const myStringState = atom({
  key: 'myString',
  default: '',
  effects_UNSTABLE: [localPersist]
});

export const myListState = atom({
  key: 'myList',
  default: [],
  effects_UNSTABLE: [localPersist]
});

Enter fullscreen mode

Exit fullscreen mode

Inside the localPersist function we have the onSet function which gets called when our atom changes. To get the state from our local storage, we use the setSelf function. Moreover, the isReset function is used when the useResetRecoilState is called.

Now that we've set the globalState.js, we now have states that are accessible to multiple components which also persists. You can check if it works by going to inspect element > Application tab > Storage > Local Storage > http://your-website-url.

Final Thoughts

Recoil is easy to implement and as seen earlier, it's similar to how we use useState. There are many new state management libraries currently existing and maybe more will be released. Jotai is an example of a state management library that is similar to Recoil–they are both atomic. Other types of libraries are flux (Redux, Zustand) and proxy (Mobs, Valtio, Overmind). At the end of the day, choosing the right library for your project depends on many variables like package size, use case, and more.


Click here to view a sample implementation of what we've discussed.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK