avatarMary Paskhaver

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

3702

Abstract

ljs-keyword">const</span> employeeSlice = <span class="hljs-title function_">createSlice</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">"employee"</span>, <span class="hljs-attr">initialState</span>: { <span class="hljs-attr">title</span>: <span class="hljs-string">"Manager"</span>, } <span class="hljs-attr">reducers</span>: { <span class="hljs-attr">setTitle</span>: <span class="hljs-function">(<span class="hljs-params">state, action</span>) =></span> { state.<span class="hljs-property">title</span> = action.<span class="hljs-property">payload</span>; } } });</pre></div><p id="7147">But you’re still responsible for making selectors and using the useDispatch hook to update the store.</p><p id="11dd">Recoil is more elegant. For example, you can define an atom like this:</p><div id="708c"><pre><span class="hljs-keyword">const</span> employeeState = <span class="hljs-title function_">atom</span>({ <span class="hljs-attr">key</span>: <span class="hljs-string">"employeeState"</span>, <span class="hljs-attr">default</span>: { <span class="hljs-attr">title</span>: <span class="hljs-string">"Manager"</span>, }, });</pre></div><p id="d120">Then use the useRecoilValue method to read the atom’s data:</p><div id="f9fa"><pre><span class="hljs-keyword">const</span> employee = <span class="hljs-title function_">useRecoilValue</span>(employeeState);</pre></div><p id="2994">And useRecoilState or useSetRecoilState to update the atom’s state:</p><div id="8ce0"><pre><span class="hljs-keyword">const</span> [employee, setEmployee] = <span class="hljs-title function_">useRecoilState</span>(employeeState); <span class="hljs-comment">// or</span> <span class="hljs-keyword">const</span> setEmployee = <span class="hljs-title function_">useSetRecoilState</span>(employeeState);</pre></div><p id="c526">This makes Recoil more intuitive than Redux.</p><ul><li><b>Redux can be slow.</b></li></ul><p id="3e48">Say you have an EmployeeProfile component that displays an employee’s ID and name. You have a list of EmployeeProfiles on the screen. Each one gets its data from the payroll reducer with a selector:</p><div id="5d0f"><pre><span class="hljs-keyword">const</span> <span class="hljs-title function_">selectEmployee</span> = id => <span class="hljs-function"><span class="hljs-params">state</span> =></span> state.<span class="hljs-property">payroll</span>.<span class="hljs-property">employees</span>[id];</pre></div><p id="331e">If you edit an employee, only the EmployeeProfile displaying that employee will re-render. But if any part of the reducer state changes, this selector will need to recalculate its return values.</p><p id="b469">Even if you use <a href="https://redux-toolkit.js.org/api/createselector/">createSelector</a> to recalculate a selector’s output only if the inputs change, Redux still has to check if the inputs changed.</p><p id="c7b7">This isn’t necessarily a big deal. The Redux docs say that most apps <a href="https://redux.js.org/faq/performance/">are not complex enough</a> to slow down because of this. But it could be worth noting if you have a complicated application.</p><p id="0aab">Recoil might handle these situations better.</p><h1 id="d961">Recoil</h1><p id="3742">Recoil was created three years ago by Facebook. Some have described it as <a href="https://www.syncfusion.com/blogs/post/recoil-the-future-of-state-management-for-react.aspx">more user-friendly</a> than Redux. It’s easy to see why: It has built-in selectors and ways to update the store. But that’s not all.</p><h2 id="55ec">Pros:</h2><ul><li><b>Recoil handles pending data.</b></li></ul><p id="a693">Recoil has a <a hre

Options

f="https://recoiljs.org/docs/api-reference/core/Loadable/">Loadable object</a> that makes it really easy to render different things depending on if an atom’s data is available.</p><p id="bc81">You can use the <a href="https://recoiljs.org/docs/api-reference/core/useRecoilValueLoadable">useRecoilValueLoadable hook</a> to read from an asynchronous selector. This hook will return a Loadable object. You can read its state property to show a loading sign if the data is loading and something else otherwise. Like in this EmployeeInfo component:</p><div id="1d89"><pre><span class="hljs-keyword">const</span> <span class="hljs-title function_">EmployeeInfo</span> = (<span class="hljs-params">{employeeID}</span>) => { <span class="hljs-keyword">const</span> employeeLoadable = <span class="hljs-title function_">useRecoilValueLoadable</span>(<span class="hljs-title function_">selectEmployee</span>(employeeID));

<span class="hljs-keyword">if</span> (employeeLoadable.<span class="hljs-property">state</span> === <span class="hljs-string">'loading'</span>) { <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">LoadingSign</span> /></span></span>; }

<span class="hljs-keyword">if</span> (employeeLoadable.<span class="hljs-property">state</span> === <span class="hljs-string">'hasValue'</span>) { <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">EmployeeProfile</span> <span class="hljs-attr">employee</span>=<span class="hljs-string">{employeeLoadable}</span> /></span></span> }

<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>; }</pre></div><h2 id="44da">Cons:</h2><ul><li><b>Recoil is larger than Redux.</b></li></ul><p id="0855">On NPM, Recoil’s unpacked size is 2.2 MB. Redux’s is 179 KB. This means Recoil is twelve times larger than Redux. Even if you used both Redux and React Redux, Recoil would still be more than four times larger.</p><p id="9952">It’s important for applications to be as small as possible. The larger an application is, the longer it takes to send it over networks, load it, and execute it.</p><p id="b963">So Recoil isn’t ideal if you want to reduce your bundle size.</p><ul><li><b>Recoil doesn’t support middleware / global states.</b></li></ul><p id="4301">You can get Recoil to change many atoms at once and work with remote databases. But as this <a href="https://github.com/facebookexperimental/Recoil/discussions/1969">GitHub discussion</a> demonstrates, it’s not super straightforward.</p><p id="f9b5">And while atoms are supposed to work with the closest RecoilRoots, it can be frustrating that <a href="https://github.com/facebookexperimental/Recoil/issues/410">they can’t really work outside components</a>.</p><p id="1592">So Recoil might not be the best choice if you want atoms to rely on persistent stateful instances.</p><h1 id="2579">Conclusion</h1><p id="d577">So, Redux and Recoil have their own benefits and drawbacks. While Redux is more established, it can be slow and requires a steeper learning curve to understand. Recoil is more React-specific but will increase your bundle size more.</p><p id="3fe1">This article only covers some basics about Redux and Recoil. If you’d like to learn more about them, <a href="https://www.syncfusion.com/blogs/post/recoil-the-future-of-state-management-for-react.aspx">this article</a> is a great place to start.</p><p id="ecea">These packages continue to grow every day. I’m excited to see what new developments they have… in store.</p><p id="219b">Haha.</p><p id="18e3">Thanks for reading.</p></article></body>

Redux vs. Recoil

Which is better?

You’ve likely heard of Redux. It’s a popular state management tool for JavaScript apps, including React sites. Its website says it’s predictable, centralized, debuggable, and flexible.

And it has some competition.

I’ve been hearing more about Recoil lately. Recoil is said to be easier to work with than Redux. But each one has its pros and cons.

Let’s take a brief look at them. But first, let’s define some of their terms.

Vocabulary

In Redux, the source of truth is in one store. In order for components to access the store, they need to be wrapped in Redux’s Provider component.

You need to define:

  • Actions to describe the shape of data sent to the store.
  • Reducers to receive and use actions to update the store.
  • Selectors to read from the store.

Understanding all these definitions takes a while.

Recoil operates differently. The state is split up into small units called atoms. In order for components to access atoms, they need to be wrapped in a RecoilRoot component.

You do not need to define:

  • Functions to update atoms.
  • Selectors to read from atoms.

These are built into Recoil.

Redux

Redux is the king of state management libraries. It’s been around for more than a decade. According to NPM Trends, Redux has more than twice as many downloads as Recoil:

But is a king always the best ruler?

Pros:

  • Redux is established.

Because it’s older and more popular than Recoil, Redux has a ton of documentation. Look at the size of the sidebar on its documentation page. It’s a lot longer than Recoil’s:

Of course, quantity does not always guarantee quality. But hundreds of companies use Redux. It’s more reliable and less experimental than Recoil.

  • Redux is more general.

Redux is for JavaScript apps, not just React ones. If you want it to work specifically with React, you can use React Redux, its companion library.

But Recoil was built as a state management library solely for React. It removes some inefficiencies that Redux has. For example, only components that read from an atom will re-render when the data in an atom changes. I’ll explain why Redux can be slower at that.

Cons

  • Redux requires more boilerplate code to use.

Remember Redux before Redux Toolkit? You had to set up constants so you could use them in your action creators so you could use them in your reducers… and so on.

Now, Redux has configureStore and createSlice methods that make life a lot easier. For example, you can define a slice with a name, state, and reducer function like this:

const employeeSlice = createSlice({
  name: "employee",
  initialState: {
    title: "Manager",
  }
  reducers: {
    setTitle: (state, action) => {
      state.title = action.payload;
    }
  }
});

But you’re still responsible for making selectors and using the useDispatch hook to update the store.

Recoil is more elegant. For example, you can define an atom like this:

const employeeState = atom({
  key: "employeeState",
  default: {
    title: "Manager",
  },
});

Then use the useRecoilValue method to read the atom’s data:

const employee = useRecoilValue(employeeState);

And useRecoilState or useSetRecoilState to update the atom’s state:

const [employee, setEmployee] = useRecoilState(employeeState);
// or
const setEmployee = useSetRecoilState(employeeState);

This makes Recoil more intuitive than Redux.

  • Redux can be slow.

Say you have an EmployeeProfile component that displays an employee’s ID and name. You have a list of EmployeeProfiles on the screen. Each one gets its data from the payroll reducer with a selector:

const selectEmployee = id => state => state.payroll.employees[id];

If you edit an employee, only the EmployeeProfile displaying that employee will re-render. But if any part of the reducer state changes, this selector will need to recalculate its return values.

Even if you use createSelector to recalculate a selector’s output only if the inputs change, Redux still has to check if the inputs changed.

This isn’t necessarily a big deal. The Redux docs say that most apps are not complex enough to slow down because of this. But it could be worth noting if you have a complicated application.

Recoil might handle these situations better.

Recoil

Recoil was created three years ago by Facebook. Some have described it as more user-friendly than Redux. It’s easy to see why: It has built-in selectors and ways to update the store. But that’s not all.

Pros:

  • Recoil handles pending data.

Recoil has a Loadable object that makes it really easy to render different things depending on if an atom’s data is available.

You can use the useRecoilValueLoadable hook to read from an asynchronous selector. This hook will return a Loadable object. You can read its state property to show a loading sign if the data is loading and something else otherwise. Like in this EmployeeInfo component:

const EmployeeInfo = ({employeeID}) => {
  const employeeLoadable = useRecoilValueLoadable(selectEmployee(employeeID));
  
  if (employeeLoadable.state === 'loading') {
    return <LoadingSign />;
  }

  if (employeeLoadable.state === 'hasValue') {
    return <EmployeeProfile employee={employeeLoadable} />
  }

  return null;
}

Cons:

  • Recoil is larger than Redux.

On NPM, Recoil’s unpacked size is 2.2 MB. Redux’s is 179 KB. This means Recoil is twelve times larger than Redux. Even if you used both Redux and React Redux, Recoil would still be more than four times larger.

It’s important for applications to be as small as possible. The larger an application is, the longer it takes to send it over networks, load it, and execute it.

So Recoil isn’t ideal if you want to reduce your bundle size.

  • Recoil doesn’t support middleware / global states.

You can get Recoil to change many atoms at once and work with remote databases. But as this GitHub discussion demonstrates, it’s not super straightforward.

And while atoms are supposed to work with the closest RecoilRoots, it can be frustrating that they can’t really work outside components.

So Recoil might not be the best choice if you want atoms to rely on persistent stateful instances.

Conclusion

So, Redux and Recoil have their own benefits and drawbacks. While Redux is more established, it can be slow and requires a steeper learning curve to understand. Recoil is more React-specific but will increase your bundle size more.

This article only covers some basics about Redux and Recoil. If you’d like to learn more about them, this article is a great place to start.

These packages continue to grow every day. I’m excited to see what new developments they have… in store.

Haha.

Thanks for reading.

Web Development
State Management
Redux
React
Technology
Recommended from ReadMedium