{"id":20587,"date":"2022-10-10T06:11:57","date_gmt":"2022-10-10T13:11:57","guid":{"rendered":"https:\/\/coderpad.io\/?p=20587"},"modified":"2023-06-05T14:02:33","modified_gmt":"2023-06-05T21:02:33","slug":"redux-vs-recoil","status":"publish","type":"post","link":"https:\/\/coderpad.io\/blog\/development\/redux-vs-recoil\/","title":{"rendered":"Redux vs Recoil &#8211; Comparing Two React State Libraries"},"content":{"rendered":"\n<p>State management is indispensable when building medium to large-scale React projects due to the large number of components that must be able to communicate with each other efficiently. Also, these large projects may have logic implemented on the front end that requires a global application state.<\/p>\n\n\n\n<p>Luckily, in addition to the state management solutions and features shipped with React, there are specialized libraries built for managing state in React applications.<\/p>\n\n\n\n<p>We\u2019ll take look at two popular options out of the many libraries out there\u2014Redux and Recoil\u2014and show you how to implement them.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What is a state management library?<\/h2>\n\n\n\n<p>A state management library provides a structure and functionalities for modeling and accessing the global application state. Data is centralized in one location, usually a \u201cstore\u201d where every component can access that data, set values, and monitor for changes.<\/p>\n\n\n\n<p>Without state management, components will be unable to get data contained in other components without the use of something like \u201c<a href=\"https:\/\/kentcdodds.com\/blog\/prop-drilling\" target=\"_blank\" rel=\"noreferrer noopener\">prop drilling<\/a>\u201d.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><a href=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/10\/img_633f213c96786.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/10\/img_633f213c96786-1024x576.png\" alt=\"Diagram of application components without state management\" class=\"wp-image-20588\" srcset=\"https:\/\/coderpad.io\/wp-content\/uploads\/2022\/10\/img_633f213c96786-1024x576.png 1024w, https:\/\/coderpad.io\/wp-content\/uploads\/2022\/10\/img_633f213c96786-300x169.png 300w, https:\/\/coderpad.io\/wp-content\/uploads\/2022\/10\/img_633f213c96786-768x432.png 768w, https:\/\/coderpad.io\/wp-content\/uploads\/2022\/10\/img_633f213c96786.png 1366w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>With state management, however, every component can have access to and write to the same application state.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><a href=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/10\/img_633f213f0c748.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/10\/img_633f213f0c748-1024x576.png\" alt=\"Diagram of application components with state management\" class=\"wp-image-20589\" srcset=\"https:\/\/coderpad.io\/wp-content\/uploads\/2022\/10\/img_633f213f0c748-1024x576.png 1024w, https:\/\/coderpad.io\/wp-content\/uploads\/2022\/10\/img_633f213f0c748-300x169.png 300w, https:\/\/coderpad.io\/wp-content\/uploads\/2022\/10\/img_633f213f0c748-768x432.png 768w, https:\/\/coderpad.io\/wp-content\/uploads\/2022\/10\/img_633f213f0c748.png 1366w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>Next, let\u2019s look at how we can use state management libraries like Redux and Recoil to manage state in our React applications.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Redux<\/h2>\n\n\n\n<p>According to the <a href=\"https:\/\/redux.js.org\/tutorials\/fundamentals\/part-1-overview#what-is-redux\" target=\"_blank\" rel=\"noreferrer noopener\">Redux docs<\/a>, \u201cRedux is <strong>a pattern and library for managing and updating application state, using events called \u2018actions\u2019.\u201d<\/strong> It serves as a centralized store for state that needs to be used across your entire application, with rules ensuring that the state can only be updated in a predictable fashion.<\/p>\n\n\n\n<p>Here are a few things the <a href=\"https:\/\/redux.js.org\/tutorials\/fundamentals\/part-1-overview\" target=\"_blank\" rel=\"noreferrer noopener\">Redux documentation<\/a> wants us to know before we proceed.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Why use Redux?<\/h3>\n\n\n\n<p>Redux manages the &#8220;global&#8221; application state &#8211; a state that is accessible across many parts of your application.<\/p>\n\n\n\n<p><strong>The patterns and tools provided by Redux make it easier to understand when, where, why, and how the state in your application is being updated, and how your application logic will behave when those changes occur<\/strong>.<\/p>\n\n\n\n<p>Redux is more useful when:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The app state is needed in numerous locations throughout the app and is regularly updated over time.<\/li>\n\n\n\n<li>The logic to update that state may be sophisticated.<\/li>\n\n\n\n<li>The app has a medium-to-large scaled codebase and might be worked on by many people.<\/li>\n<\/ul>\n\n\n\n<p><strong>Not all applications require Redux. Spend some time considering the type of app you&#8217;re creating and deciding which tools would be most helpful in resolving the issues you&#8217;re working on.<\/strong><\/p>\n\n\n\n<p>Now that that\u2019s out of the way, let\u2019s set up Redux in a React application.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Redux components and terminology<\/h3>\n\n\n\n<p>Redux Store, Action, and Reducer are the three main parts of Redux.<\/p>\n\n\n\n<p><strong>Redux Store <\/strong>is the \u201cbrain\u201d of our state management structure.&nbsp;<\/p>\n\n\n\n<p>It manages the state and dispatches Actions<\/p>\n\n\n\n<p><strong>Dispatch<\/strong> is a method in the Redux store. The state can only be updated by calling <code>store.dispatch()<\/code> and providing an action object.<\/p>\n\n\n\n<p><strong>Action<\/strong> refers to the commands passed to the Reducers, which can be interpreted by it. It stores information regarding the user&#8217;s actions.&nbsp; There is a type and a payload in the action. The payload contains the actual data provided by the action, whereas the type is only a string with the action name.<\/p>\n\n\n\n<p><strong>Reducers<\/strong> are functions that read the instructions sent by the Action and update the store using the state. Reducers specify how the application&#8217;s state will change in response to the actions sent to the store.<\/p>\n\n\n\n<p>We will use a counter application as a case study as we move on, to discuss how to set up and use Redux in an app.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Install and setup Redux<\/h3>\n\n\n\n<p>Add Redux Toolkit and React Redux packages to your project:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\"><span class=\"hljs-selector-tag\">npm<\/span> <span class=\"hljs-selector-tag\">install<\/span> <span class=\"hljs-keyword\">@reduxjs<\/span>\/toolkit react-redux<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Create a Redux Store<\/h3>\n\n\n\n<p>Create a new file &#8211; <code>.\/src\/store\/index.js.<\/code>&nbsp;<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ .\/src\/store\/index.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> { configureStore } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@reduxjs\/toolkit'<\/span>\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> configureStore({\n\u00a0 <span class=\"hljs-attr\">reducer<\/span>: {},\n})<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Here, we import the <code>configureStore<\/code> API from Redux Toolkit and create an empty Redux store, and export it.<\/p>\n\n\n\n<p>This creates a Redux store with an empty <code>reducer<\/code> function. Next, we\u2019ll have to make the store accessible for the rest of our React application.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Provide Redux store to the application<\/h3>\n\n\n\n<p>We can make the newly created store available to our React components by importing and wrapping the React Redux <code>&lt;Provider&gt;<\/code> over the application. We\u2019ll do all that in the <code>.\/src\/index.js<\/code> file.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">.\/src\/index.js\n\n<span class=\"hljs-keyword\">import<\/span> { StrictMode } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { createRoot } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react-dom\/client\"<\/span>;\n\n<span class=\"hljs-comment\">\/\/ import Provider<\/span>\n<span class=\"hljs-keyword\">import<\/span> { Provider } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react-redux\"<\/span>;\n\n<span class=\"hljs-comment\">\/\/ import store<\/span>\n<span class=\"hljs-keyword\">import<\/span> store <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/store\/index\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> App <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/App\"<\/span>;\n<span class=\"hljs-keyword\">const<\/span> rootElement = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"root\"<\/span>);\n<span class=\"hljs-keyword\">const<\/span> root = createRoot(rootElement);\nroot.render(\n\n\u00a0 <span class=\"hljs-comment\">\/\/ wrap application with Provider<\/span>\n\u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Provider<\/span> <span class=\"hljs-attr\">store<\/span>=<span class=\"hljs-string\">{store}<\/span>&gt;<\/span>\n\u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">StrictMode<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">App<\/span> \/&gt;<\/span>\n\u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">StrictMode<\/span>&gt;<\/span>\n\u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Provider<\/span>&gt;<\/span><\/span>\n);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Create Redux state slice(s)<\/h3>\n\n\n\n<p>We\u2019ll create redux state slices for two pieces of state: <code>booksSlice<\/code> and <code>savedBooksSlice<\/code>.&nbsp;<\/p>\n\n\n\n<p>Creating a slice requires a string name to identify the slice, an initial state value, and one or more reducer functions to define how the state can be updated. Once a slice is created, we can export the generated Redux action creators and the reducer function for the whole slice.<\/p>\n\n\n\n<p>First, create a slice for our books array state in a new file: <code>.\/src\/store\/books\/booksSlice.js<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ .\/src\/store\/books\/booksSlice.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> { createSlice } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"@reduxjs\/toolkit\"<\/span>;\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> booksSlice = createSlice({\n\u00a0 <span class=\"hljs-attr\">name<\/span>: <span class=\"hljs-string\">\"books\"<\/span>,\n\u00a0 <span class=\"hljs-attr\">initialState<\/span>: {\n\u00a0 \u00a0 <span class=\"hljs-attr\">value<\/span>: &#91;\n\u00a0 \u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">id<\/span>: <span class=\"hljs-string\">\"001\"<\/span>,\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">title<\/span>: <span class=\"hljs-string\">\"Harry Potter and the Deathly Hallows\"<\/span>,\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">price<\/span>: <span class=\"hljs-number\">5.0<\/span>,\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">rating<\/span>: <span class=\"hljs-string\">\"5.0\"<\/span>\n\u00a0 \u00a0 \u00a0 },\n\u00a0 \u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">id<\/span>: <span class=\"hljs-string\">\"002\"<\/span>,\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">title<\/span>: <span class=\"hljs-string\">\"Harry Potter and the Goblet of Fire\"<\/span>,\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">price<\/span>: <span class=\"hljs-number\">5.0<\/span>,\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">rating<\/span>: <span class=\"hljs-string\">\"4.8\"<\/span>\n\u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 ]\n\u00a0 },\n\u00a0 <span class=\"hljs-attr\">reducers<\/span>: {\n\u00a0 \u00a0 <span class=\"hljs-attr\">set<\/span>: <span class=\"hljs-function\">(<span class=\"hljs-params\">state, action<\/span>) =&gt;<\/span> {\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-keyword\">return<\/span> action.payload;\n\u00a0 \u00a0 }\n\u00a0 }\n});\n\n<span class=\"hljs-comment\">\/\/ Action creators are generated for each case reducer function<\/span>\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> { <span class=\"hljs-keyword\">set<\/span> } = booksSlice.actions;\n\nexport default booksSlice.reducer;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Here, we import the <code>createSlice<\/code> API from Redux Toolkit and export <code>booksSlice<\/code>, and define the <code>name<\/code>, <code>initialState<\/code>, and <code>reducers<\/code> using <code>createSlice<\/code>.<\/p>\n\n\n\n<p>Next, we\u2019ll create a state slice for <code>savedBooks<\/code>. Create a new file: <code>.\/src\/store\/books\/booksSlice.js<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ .\/src\/store\/books\/booksSlice.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> { createSlice } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"@reduxjs\/toolkit\"<\/span>;\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> savedBooksSlice = createSlice({\n\u00a0 <span class=\"hljs-attr\">name<\/span>: <span class=\"hljs-string\">\"savedBooks\"<\/span>,\n\u00a0 <span class=\"hljs-attr\">initialState<\/span>: &#91;],\n\u00a0 <span class=\"hljs-attr\">reducers<\/span>: {\n\u00a0 \u00a0 <span class=\"hljs-attr\">add<\/span>: <span class=\"hljs-function\">(<span class=\"hljs-params\">state, action<\/span>) =&gt;<\/span> {\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-comment\">\/\/ get the payload object from by destructuring the action parameter<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-comment\">\/\/\u00a0 assign value of payload to book<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-keyword\">const<\/span> { <span class=\"hljs-attr\">payload<\/span>: book } = action;\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-keyword\">return<\/span> &#91;...state, book];\n\u00a0 \u00a0 },\n\u00a0 \u00a0 <span class=\"hljs-attr\">remove<\/span>: <span class=\"hljs-function\">(<span class=\"hljs-params\">state, action<\/span>) =&gt;<\/span> {\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-comment\">\/\/ get the payload object from by destructuring the action parameter<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-comment\">\/\/\u00a0 assign value of payload to bok<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-keyword\">const<\/span> { <span class=\"hljs-attr\">payload<\/span>: book } = action;\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-keyword\">const<\/span> bookIndex = state.findIndex(<span class=\"hljs-function\">(<span class=\"hljs-params\">x<\/span>) =&gt;<\/span> x.title === book.title);\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-comment\">\/\/ if no match, return the previous state<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-keyword\">if<\/span> (bookIndex &lt; <span class=\"hljs-number\">0<\/span>) <span class=\"hljs-keyword\">return<\/span> state;\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-comment\">\/\/ avoid mutating the original state, create a copy<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-keyword\">const<\/span> stateUpdate = &#91;...state];\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-comment\">\/\/ then splice it out from the array<\/span>\n\u00a0 \u00a0 \u00a0 stateUpdate.splice(bookIndex, <span class=\"hljs-number\">1<\/span>);\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-keyword\">return<\/span> stateUpdate;\n\u00a0 \u00a0 }\n\u00a0 }\n});\n\n<span class=\"hljs-comment\">\/\/ Action creators are generated for each case reducer function<\/span>\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> { add, remove } = savedBooksSlice.actions;\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> savedBooksSlice.reducer;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Next, we\u2019ll make these state slices global by importing them into our store.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Add slice reducers to the store<\/h3>\n\n\n\n<p>Now, we need to import the reducer functions from the state slices and add it to our store. Back in <code>.\/src\/store\/index.js<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ .\/src\/store\/index.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> { configureStore } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"@reduxjs\/toolkit\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> savedBooksReducer <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/books\/savedBooksSlice\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> booksReducer <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/books\/booksSlice\"<\/span>;\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> configureStore({\n\u00a0 <span class=\"hljs-attr\">reducer<\/span>: {\n\u00a0 \u00a0 <span class=\"hljs-attr\">books<\/span>: booksReducer,\n\u00a0 \u00a0 <span class=\"hljs-attr\">savedBooks<\/span>: savedBooksReducer\n\u00a0 }\n});<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Now that we\u2019ve configured our store, let&#8217;s use our state in our components<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Use Redux state and actions in React components<\/h3>\n\n\n\n<p>Now we can use the React Redux hooks to let React components interact with the Redux store. We can read the data from the store with <code>useSelector<\/code>, and dispatch actions using <code>useDispatch<\/code>.&nbsp;<\/p>\n\n\n\n<p>First, in <code>.\/src\/SavedBooks.js<\/code> component, we\u2019ll use <code>useSelector<\/code> to read the <code>savedBooks<\/code> data.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> React <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { useSelector } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react-redux\"<\/span>;\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">SavedBooks<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\u00a0 <span class=\"hljs-keyword\">const<\/span> savedBooks = useSelector(<span class=\"hljs-function\">(<span class=\"hljs-params\">state<\/span>) =&gt;<\/span> state.savedBooks);\n\u00a0 <span class=\"hljs-comment\">\/\/ function to get total price from savedbooks array<\/span>\n\u00a0 <span class=\"hljs-keyword\">const<\/span> getTotalPrice = <span class=\"hljs-function\">(<span class=\"hljs-params\">savedBooks<\/span>) =&gt;<\/span> {\n\u00a0 \u00a0 <span class=\"hljs-keyword\">const<\/span> totalPrice = savedBooks.reduce(\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-function\">(<span class=\"hljs-params\">totalCost, item<\/span>) =&gt;<\/span> totalCost + item.price,\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-number\">0<\/span>\n\u00a0 \u00a0 );\n\u00a0 \u00a0 <span class=\"hljs-keyword\">return<\/span> totalPrice;\n\u00a0 };\n\u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">header<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span> No. of Books: {savedBooks.length} <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span> Total price: ${getTotalPrice(savedBooks)} <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">header<\/span>&gt;<\/span><\/span>\n\u00a0 );\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Next, we\u2019ll use <code>useSelector<\/code> and <code>useDispatch<\/code> to read and update the <code>books<\/code> and <code>savedBooks<\/code> state respectively in the <code>.\/src\/Books.js<\/code> component.<\/p>\n\n\n\n<p>To dispatch the actions <code>add<\/code> and <code>remove<\/code> we need to import the actions and use the <code>useDispatch<\/code> hook provided by react-redux to dispatch our actions.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ .\/src\/Books.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> React <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { useSelector, useDispatch } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react-redux\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { add, remove } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/store\/books\/savedBooksSlice\"<\/span>;\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">Books<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\u00a0 <span class=\"hljs-keyword\">const<\/span> dispatch = useDispatch();\n\u00a0 <span class=\"hljs-keyword\">const<\/span> books = useSelector(<span class=\"hljs-function\">(<span class=\"hljs-params\">state<\/span>) =&gt;<\/span> state.books.value);\n\u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ul<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"Books\"<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 {books.map((book) =&gt; {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 return (\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"book\"<\/span> <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{book.title}<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">header<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h3<\/span>&gt;<\/span> {book.title} <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h3<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>Rating: {book.rating} <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span> ${book.price} <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">header<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{()<\/span> =&gt;<\/span> dispatch(add(book))}&gt; Add <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{()<\/span> =&gt;<\/span> dispatch(remove(book))}&gt; Remove <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 );\n\u00a0 \u00a0 \u00a0 \u00a0 })}\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">ul<\/span>&gt;<\/span>\n\u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n\u00a0 );\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n<div\n\tclass=\"sandbox-embed responsive-embed \"\n\tstyle=\"padding-top: 125%\"\ndata-block-name=\"coderpad-sandbox-embed\">\n\t<iframe src=\"https:\/\/embed.coderpad.io\/sandbox?question_id=230577&#038;use_question_button\" width=\"640\" height=\"800\" loading=\"lazy\" aria-label=\"Try out the CoderPad sandbox\"><\/iframe>\n<\/div>\n\n\n\n<p>Great! Now, our app works with Redux!<\/p>\n\n\n\n<p>Next, we\u2019ll explore another interesting state management library &#8211; Recoil<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Recoil<\/h2>\n\n\n\n<p>Recoil, according to <a href=\"https:\/\/recoiljs.org\/docs\/introduction\/core-concepts\/#:~:text=Overview%E2%80%8B,state%20either%20synchronously%20or%20asynchronously.\" target=\"_blank\" rel=\"noopener\">its docs<\/a>, is a newer state management library built by the Facebook open-source community. It\u2019s best explained by looking at the core concepts from the docs, which we recap below.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Recoil components and terminology<\/h3>\n\n\n\n<p>Recoil lets you create a data-flow graph that flows from <em>atoms<\/em> (shared state) through <em>selectors<\/em> (pure functions) and down into your React components. Atoms are units of state that components can subscribe to. Selectors transform this state either synchronously or asynchronously.<\/p>\n\n\n\n<p><strong>Atoms<\/strong> are units of state. They&#8217;re updatable and subscribable: when an atom is updated, each subscribed component is re-rendered with the new value.<\/p>\n\n\n\n<p>A <strong>selector<\/strong> is a pure function that accepts atoms or other selectors as input. When these upstream atoms or selectors are updated, the selector function will be re-evaluated. Components can subscribe to selectors just like atoms, and will then be re-rendered when the selectors change.<\/p>\n\n\n\n<p>You can <a href=\"https:\/\/recoiljs.org\/docs\/introduction\/core-concepts\" target=\"_blank\" rel=\"noopener\">find out more from the documentation<\/a>.<\/p>\n\n\n\n<p>Let\u2019s move on and see how we can use Recoil in our React application. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Install and set up Recoil<\/h3>\n\n\n\n<p>To install the latest stable version, run the following command:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\"><span class=\"hljs-selector-tag\">npm<\/span> <span class=\"hljs-selector-tag\">install<\/span> <span class=\"hljs-selector-tag\">recoil<\/span>\n<span class=\"hljs-selector-id\">#or<\/span>\n<span class=\"hljs-selector-tag\">yarn<\/span> <span class=\"hljs-selector-tag\">add<\/span> <span class=\"hljs-selector-tag\">recoil<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Now that we have Recoil installed, we have to add <code>RecoilRoot<\/code> to our app\u2019s root component in <code>.\/src\/App.js<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ .\/src\/App.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> { Books } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/Books\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { SavedBooks } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/SavedBooks\"<\/span>;\n\n<span class=\"hljs-comment\">\/\/ import RecoilRoot<\/span>\n<span class=\"hljs-keyword\">import<\/span> { RecoilRoot } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"recoil\"<\/span>;\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">App<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">RecoilRoot<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"App\"<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">SavedBooks<\/span> \/&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Books<\/span> \/&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">RecoilRoot<\/span>&gt;<\/span><\/span>\n\u00a0 );\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Next, we\u2019ll create our atoms which will contain our <code>books<\/code> and <code>savedBooks<\/code> state.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Create books state atom<\/h3>\n\n\n\n<p>Create a new file <code>.\/src\/atoms\/books.js<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ .\/src\/atoms\/books.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> { atom } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"recoil\"<\/span>;\n<span class=\"hljs-keyword\">const<\/span> booksState = atom({\n\u00a0 <span class=\"hljs-attr\">key<\/span>: <span class=\"hljs-string\">\"books\"<\/span>,\n\u00a0 <span class=\"hljs-attr\">default<\/span>: &#91;\n\u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">id<\/span>: <span class=\"hljs-string\">\"001\"<\/span>,\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">title<\/span>: <span class=\"hljs-string\">\"Harry Potter and the Deathly Hallows\"<\/span>,\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">price<\/span>: <span class=\"hljs-number\">5.0<\/span>,\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">rating<\/span>: <span class=\"hljs-string\">\"5.0\"<\/span>\n\u00a0 \u00a0 },\n\u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">id<\/span>: <span class=\"hljs-string\">\"002\"<\/span>,\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">title<\/span>: <span class=\"hljs-string\">\"Harry Potter and the Goblet of Fire\"<\/span>,\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">price<\/span>: <span class=\"hljs-number\">5.0<\/span>,\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">rating<\/span>: <span class=\"hljs-string\">\"4.8\"<\/span>\n\u00a0 \u00a0 }\n\u00a0 ]\n});\n\n<span class=\"hljs-keyword\">export<\/span> { booksState };<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Create savedBooks atom state<\/h3>\n\n\n\n<p>Create another file <code>.\/src\/atoms\/savedBooks.js<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ .\/src\/atoms\/savedBooks.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> { atom } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"recoil\"<\/span>;\n<span class=\"hljs-keyword\">const<\/span> savedBooksState = atom({\n\u00a0 <span class=\"hljs-attr\">key<\/span>: <span class=\"hljs-string\">\"savedBooks\"<\/span>,\n\u00a0 <span class=\"hljs-attr\">default<\/span>: &#91;]\n});\n<span class=\"hljs-keyword\">export<\/span> { savedBooksState };\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In order to read from <em>and<\/em> write to an atom, Components should use <code>useRecoilState()<\/code>. This means, to use the <code>books<\/code> atom state in the <code>Books<\/code> component, we simply import <code>useRecoilState()<\/code> and <code>booksState<\/code>.<\/p>\n\n\n\n<p>To read from an atom, we use <code>useRecoilValue<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ .\/src\/Books.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> React <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { useRecoilValue } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"recoil\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { booksState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/atoms\/books\"<\/span>;\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">Books<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\u00a0 <span class=\"hljs-keyword\">const<\/span> books = useRecoilValue(booksState);\n\n\u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">{{<\/span> <span class=\"hljs-attr\">border:<\/span> \"<span class=\"hljs-attr\">1px<\/span> <span class=\"hljs-attr\">solid<\/span>\" }}&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ul<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"Books\"<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 {books.map((book) =&gt; {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 return (\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"book\"<\/span> <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{book.title}<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">header<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h3<\/span>&gt;<\/span> {book.title} <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h3<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>Rating: {book.rating} <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span> ${book.price} <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">header<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 );\n\u00a0 \u00a0 \u00a0 \u00a0 })}\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">ul<\/span>&gt;<\/span>\n\u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n\u00a0 );\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Also, we can do the same thing in our <code>savedBooks<\/code> component &#8211; <code>.\/src\/SavedBooks.js<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ .\/src\/SavedBooks.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> React <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { useRecoilValue } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"recoil\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { savedBooksState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/atoms\/savedBooks\"<\/span>;\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">SavedBooks<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\u00a0 <span class=\"hljs-keyword\">const<\/span> savedBooks = useRecoilValue(savedBooksState);\n\u00a0 <span class=\"hljs-comment\">\/\/ function to get total price from savedbooks array<\/span>\n\u00a0 <span class=\"hljs-keyword\">const<\/span> getTotalPrice = <span class=\"hljs-function\">(<span class=\"hljs-params\">savedBooks<\/span>) =&gt;<\/span> {\n\u00a0 \u00a0 <span class=\"hljs-keyword\">const<\/span> totalPrice = savedBooks.reduce(\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-function\">(<span class=\"hljs-params\">totalCost, item<\/span>) =&gt;<\/span> totalCost + item.price,\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-number\">0<\/span>\n\u00a0 \u00a0 );\n\u00a0 \u00a0 <span class=\"hljs-keyword\">return<\/span> totalPrice;\n\u00a0 };\n\u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">header<\/span> <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">{{<\/span> <span class=\"hljs-attr\">border:<\/span> \"<span class=\"hljs-attr\">1px<\/span> <span class=\"hljs-attr\">solid<\/span>\", <span class=\"hljs-attr\">marginBottom:<\/span> \"<span class=\"hljs-attr\">6px<\/span>\" }}&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span> No. of Books: {savedBooks.length} <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span> Total price: ${getTotalPrice(savedBooks)} <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">header<\/span>&gt;<\/span><\/span>\n\u00a0 );\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Now that we know how to read our state, how do we modify it?<\/p>\n\n\n\n<p>To do that we have to do a few things. Let\u2019s bring the <code>add<\/code> and <code>remove<\/code> functions into our <code>Books<\/code> component:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ .src\/Books.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> React <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { useRecoilValue, useSetRecoilState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"recoil\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { booksState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/atoms\/books\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { savedBooksState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/atoms\/savedBooks\"<\/span>;\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">Books<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\u00a0 <span class=\"hljs-keyword\">const<\/span> books = useRecoilValue(booksState);\n\u00a0 <span class=\"hljs-keyword\">const<\/span> setSavedBooks = useSetRecoilState(savedBooksState);\n\u00a0 <span class=\"hljs-keyword\">const<\/span> add = <span class=\"hljs-function\">(<span class=\"hljs-params\">book<\/span>) =&gt;<\/span> {\n\u00a0 \u00a0 <span class=\"hljs-comment\">\/\/\u00a0 assign value of payload to bok<\/span>\n\u00a0 \u00a0 setSavedBooks(<span class=\"hljs-function\">(<span class=\"hljs-params\">state<\/span>) =&gt;<\/span> {\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-keyword\">return<\/span> &#91;...state, book];\n\u00a0 \u00a0 });\n\u00a0 };\n\u00a0 <span class=\"hljs-keyword\">const<\/span> remove = <span class=\"hljs-function\">(<span class=\"hljs-params\">book<\/span>) =&gt;<\/span> {\n\u00a0 \u00a0 <span class=\"hljs-comment\">\/\/\u00a0 assign value of payload to bok<\/span>\n\u00a0 \u00a0 setSavedBooks(<span class=\"hljs-function\">(<span class=\"hljs-params\">state<\/span>) =&gt;<\/span> {\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-keyword\">const<\/span> bookIndex = state.findIndex(<span class=\"hljs-function\">(<span class=\"hljs-params\">x<\/span>) =&gt;<\/span> x.title === book.title);\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-comment\">\/\/ if no match, return the previous state<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-keyword\">if<\/span> (bookIndex &lt; <span class=\"hljs-number\">0<\/span>) <span class=\"hljs-keyword\">return<\/span> state;\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-comment\">\/\/ avoid mutating the original state, create a copy<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-keyword\">const<\/span> stateUpdate = &#91;...state];\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-comment\">\/\/ then splice it out from the array<\/span>\n\u00a0 \u00a0 \u00a0 stateUpdate.splice(bookIndex, <span class=\"hljs-number\">1<\/span>);\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-keyword\">return<\/span> stateUpdate;\n\u00a0 \u00a0 });\n\u00a0 };\n\u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">{{<\/span> <span class=\"hljs-attr\">border:<\/span> \"<span class=\"hljs-attr\">1px<\/span> <span class=\"hljs-attr\">solid<\/span>\" }}&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ul<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"Books\"<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 {books.map((book) =&gt; {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 return (\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"book\"<\/span> <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{book.title}<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">header<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h3<\/span>&gt;<\/span> {book.title} <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h3<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>Rating: {book.rating} <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span> ${book.price} <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">header<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{()<\/span> =&gt;<\/span> add(book)}&gt; Add <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{()<\/span> =&gt;<\/span> remove(book)}&gt; Remove <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 );\n\u00a0 \u00a0 \u00a0 \u00a0 })}\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">ul<\/span>&gt;<\/span>\n\u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n\u00a0 );\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n<div\n\tclass=\"sandbox-embed responsive-embed \"\n\tstyle=\"padding-top: 125%\"\ndata-block-name=\"coderpad-sandbox-embed\">\n\t<iframe src=\"https:\/\/embed.coderpad.io\/sandbox?question_id=230582&#038;use_question_button\" width=\"640\" height=\"800\" loading=\"lazy\" aria-label=\"Try out the CoderPad sandbox\"><\/iframe>\n<\/div>\n\n\n\n<p>In the code above, you can see that we assigned <code>const setSavedBooks = useSetRecoilState(savedBooksState)<\/code>.<\/p>\n\n\n\n<p>With this, we can modify our <code>savedBooksState<\/code> atom which we did by using <code>setSavedBooks<\/code> within our <code>add<\/code> and <code>remove<\/code> functions.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Using selectors<\/h3>\n\n\n\n<p>Remember our <code>getTotalPrice<\/code> function which dynamically gets the total price of saved books? We\u2019ll use a selector to dynamically render the total price of the items in the <code>savedBooks<\/code> array.<\/p>\n\n\n\n<p>First, we have to create a new file <code>.\/src\/selectors\/totalPrice.js<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ .\/src\/selectors\/totalPrice.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> { selector } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"recoil\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { savedBooksState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/atoms\/savedBooks\"<\/span>;\n<span class=\"hljs-keyword\">const<\/span> totalPrice = selector({\n\u00a0 <span class=\"hljs-attr\">key<\/span>: <span class=\"hljs-string\">\"getTotalPrice\"<\/span>,\n\u00a0 <span class=\"hljs-attr\">get<\/span>: <span class=\"hljs-function\">(<span class=\"hljs-params\">{ get }<\/span>) =&gt;<\/span> {\n\u00a0 \u00a0 <span class=\"hljs-keyword\">const<\/span> savedBooks = <span class=\"hljs-keyword\">get<\/span>(savedBooksState);\n\u00a0 \u00a0 const totalPrice = savedBooks.reduce(\n\u00a0 \u00a0 \u00a0 (totalCost, item) =&gt; totalCost + item.price,\n\u00a0 \u00a0 \u00a0 0\n\u00a0 \u00a0 );\n\u00a0 \u00a0 return totalPrice;\n\u00a0 }\n});\nexport { totalPrice };<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The <code>totalPrice<\/code> selector keeps track of <code>savedBooksState<\/code> and re-runs if there are any changes.<\/p>\n\n\n\n<p>Back in the <code>SavedBooks<\/code> component, we import our selector and use it.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ .\/src\/SavedBooks.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> React <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { useRecoilValue } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"recoil\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { savedBooksState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/atoms\/savedBooks\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { totalPrice } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/selectors\/totalPrice\"<\/span>;\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">SavedBooks<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\u00a0 <span class=\"hljs-keyword\">const<\/span> savedBooks = useRecoilValue(savedBooksState);\n\u00a0 <span class=\"hljs-keyword\">const<\/span> getTotalPrice = useRecoilValue(totalPrice);\n\u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">header<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span> No. of Books: {savedBooks.length} <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span> Total price: ${getTotalPrice} <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">header<\/span>&gt;<\/span><\/span>\n\u00a0 );\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n<div\n\tclass=\"sandbox-embed responsive-embed \"\n\tstyle=\"padding-top: 125%\"\ndata-block-name=\"coderpad-sandbox-embed\">\n\t<iframe src=\"https:\/\/embed.coderpad.io\/sandbox?question_id=230590&#038;use_question_button\" width=\"640\" height=\"800\" loading=\"lazy\" aria-label=\"Try out the CoderPad sandbox\"><\/iframe>\n<\/div>\n\n\n\n<p>There we go! We\u2019ve successfully used Recoil for state management in our React application.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Other state libraries to consider<\/h2>\n\n\n\n<p>Between this article and <a href=\"https:\/\/coderpad.io\/blog\/development\/global-state-management-react\/\" target=\"_blank\" rel=\"noreferrer noopener\">Global State Management in React without a Library<\/a>, you\u2019ve learned how to handle state in React apps using a variety of methods and tools, including Redux and Recoil for medium to big projects and Hooks and Context API for small to medium projects.<\/p>\n\n\n\n<p>Nevertheless, the React ecosystem provides a wide range of state libraries. The majority of them were developed and constructed with a particular idea and use case in mind, so if you want to use any of them, you&#8217;ll probably have a good reason for doing so.<\/p>\n\n\n\n<p>A few of them include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/github.com\/pmndrs\/zustand\" target=\"_blank\" rel=\"noreferrer noopener\">Zustand<\/a> &#8211; a state-management solution that is compact, quick, and scalable. It is particularly concerned with module state. This library is independent and is based on Hooks.<\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/pmndrs\/jotai#readme\" target=\"_blank\" rel=\"noreferrer noopener\">Jotai<\/a> &#8211; a simple and extensible React state management library that offers a simple API. It is designed for computed values and asynchronous actions to state, and it supports TypeScript.<\/li>\n\n\n\n<li><a href=\"https:\/\/mobx.js.org\/README.html\" target=\"_blank\" rel=\"noreferrer noopener\">Mobx <\/a>&#8211; &nbsp;an independent stage-management library that isn&#8217;t platform-specific, thus it can be used outside of React. It applies functional reactive programming in a transparent manner (TFRP). Different Stores are supported by MobX, unlike certain libraries like Redux. <a href=\"https:\/\/mobx.js.org\/README.html\" target=\"_blank\" rel=\"noreferrer noopener\">MobX<\/a> has a relatively low learning curve, so getting started with it is simple.&nbsp;<\/li>\n<\/ul>\n\n\n\n<p><em>My name is<\/em>&nbsp;<em>Victory Tuduo and I am a software developer who loves building web applications, creating flexible UI designs, mentoring, and writing technical articles.<\/em>&nbsp;<em>You can find out more about me and my work&nbsp;<a href=\"https:\/\/twitter.com\/vhicktri\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>&nbsp;and&nbsp;<a href=\"https:\/\/victorytuduo.vercel.app\/\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The React state can be managed directly in-app or via state management libraries. This article compares two state management libraries, Redux and Recoil, and helps you choose which is best for your application&#8217;s needs.<\/p>\n","protected":false},"author":12,"featured_media":20632,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[9],"tags":[],"persona":[29],"blog-programming-language":[61],"keyword-cluster":[],"class_list":["post-20587","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development"],"acf":[],"_links":{"self":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/20587","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/comments?post=20587"}],"version-history":[{"count":73,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/20587\/revisions"}],"predecessor-version":[{"id":34564,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/20587\/revisions\/34564"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/media\/20632"}],"wp:attachment":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/media?parent=20587"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/categories?post=20587"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/tags?post=20587"},{"taxonomy":"persona","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/persona?post=20587"},{"taxonomy":"blog-programming-language","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/blog-programming-language?post=20587"},{"taxonomy":"keyword-cluster","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/keyword-cluster?post=20587"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}