DEV Community

Jimmy McBride
Jimmy McBride

Posted on • Updated on

Redux Hooks!

The react-redux library has recently come out with two new hooks that offer us an alternative to the connect HOC, when in a functional component. So, first, let's take at what the connect HOC does:

import React, { useEffect } from "react";

// We need to import connect
import connect from "react-redux";

// We're importing our action function from our actions store
import { actionFunction } from "./store/actions/actionFile"

function App() {

  /* Since we have added our action function to the object in our
  connect HOC we can access that function through props */
  const onClick = () => props.actionFunction()

  return (
    <div>
      <h1>Hello, world!</h2>
      {/* we have mapped out the state from our reducer to 
      our props where we can access it now */}
      <button onClick={onClick}>{props.stateIWant}</button>
    </div>
  );
}

const mapStateToProps = state => {
  return {
    stateIWant: state.reducer.stateIWant
  }
};

/* connect HOC takes in a mapStateToProps function as first object
and takes in an object that we can add our action functions too so
that we can dispatch our actions */
export default connect(
  mapStateToProps, 
  { actionFunction }
)(App);
Enter fullscreen mode Exit fullscreen mode

Now let's take a look at this same code, but using redux hooks instead of the connect HOC:

import React, { useEffect } from "react";

// These are the two hooks we get from the react redux api
import { useSelector, useDispatch } from "react-redux";
// useSelector replaces the mapStateToProps in our connect HOC
// useDispatch replaces the object we add our action functions to

// We're importing our action function from our actions store
import { actionFunction } from "./store/actions/actionFile";

export default function App() {
  // This is the convention for setting up your useDispatch every time
  const dispatch = useDispatch();

  /* We are passing our action function through our useDispatch so that
  we can dispatch our action function */
  const onClick = () => dispatch(actionFunction());

  // Here we are using useSelector to grab the state we want from our reducer
  const stateIWant = useSelector(state => state.reducer.stateIWant)

  return (
    <div>
      <h1>Hello, world!</h2>
      {/* we no longer need to access stateIWant from props because we gave it
      it's own variable */}
      <button onClick={onClick}>{stateIWant}</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Don't forget! You can always deconstruct multiple pieces of state from a reducer with useSelector as well...

const { first, second, third } = useSelector(state => state.reducer)
// Is equivalent to:
const first = useSelector(state => state.reducer.first)
const second = useSelector(state => state.reducer.second)
const third = useSelector(state => state.reducer.third)
Enter fullscreen mode Exit fullscreen mode

Conclusion

I think when working with functional components, the redux hooks offer an elegant alternative to the connect HOC. Personally I quite prefer them over connect. Writing out all the boilerplate for the connect HOC always seemed a little burdensome for me.

What do you think? Do the new react-redux hooks are worth using? Or do you plan on sticking with 'old faithful' connect HOC? I'd love to hear your thoughts in the comments! See you guys again soon.

Discussion (14)

Collapse
leob profile image
leob

Yeah I do see that it's shorter and simpler ... and technically/functionally/performance-wise it is identical?

Collapse
jimmymcbride profile image
Jimmy McBride Author

I haven't done any prefromance testing comparing the two, but I would imagine that if there is a difference it's negligible.

Hooks are typically very preformant in general and so are HOC's (depending on how you would them obviously).

Even if the hooks were a few milliseconds slower that the HOC I would still use the hooks for readability and the developer experience.

I feel like there's a lot of people out there who freak out if something takes 100ms instead of 10ms and really, no user is going to notice the difference. Even though 10ms is 10 times faster than 100ms your users are going to notice it. They're not going to be like, "Wow! That's fast!".

Prefromance has its place and is incredibly important, but I think readability and developer experience is more important than small boosts in preformance. You're likely to get a lot more preformance out of optimizing the photos on your page than you would from switching from a HOC to hook.

Collapse
leob profile image
leob • Edited on

I'm asking because I remember having read an article quite long ago where the author elaborated on how "connect" was optimized for performance in all kinds of subtle and complicated ways, and how it was difficult to pull off the same with hooks.

BUT, I suspect that that was based on the state of the art back then when hooks were brand new, and I guess that the hooks that you mention did not even exist at that time! In other words, the author described how to replace "connect" with the generic hooks available then and the performance issues it caused.

Probably these new "Redux specific" hooks were created to address just that, the new hooks being a 1:1 drop-in replacement for 'connect', delivering the same performance and benefits, just with a different syntax ... so probably this is no longer an issue.

But in case you're interested, here's that article (it's from July 2019):
medium.com/javascript-scene/do-rea...

Erratum:

The link above was in fact not the article I had in mind, the one I meant is this one:
itnext.io/how-existing-redux-patte...

Thread Thread
jimmymcbride profile image
Jimmy McBride Author

That's cool! I'm going to check into that. Thanks for sharing!🔥

Thread Thread
leob profile image
leob

Haha but I sent you the wrong article! That article from Eric Elliot is more a grab bag of ideas and he doesn't do an in-depth comparison of Connect vs the Redux hooks ... I was confused, and the article I really meant is this one:

itnext.io/how-existing-redux-patte...

This article goes into great depth comparing the performance of Connect with the Redux hooks in various scenarios.

It all revolves around the overhead of causing unnecessary re-renders, and he shows how to "measure" that. And, what he claims is that Connect is doing automatic 'referential caching', which would also be possible with the hooks but it's not "built in".

In his summary titled So should I start using the Redux Hooks? he says that:

"When you move away from connect you lose a lot of the performance benefits it provides ... this means that you’ll have to be more cautious when considering re-renders"

But to determine if this claim is justified (and what it means) you'll have to read the rest of the article.

You can read Eric Elliott's article if you like, however the one I meant was in fact this one!

Thread Thread
leob profile image
leob

P.S. so you think he has a point that Connect still has potential advantages with its "baked in intelligence" to prevent re-renders?

Thread Thread
jimmymcbride profile image
Jimmy McBride Author

You can do it all on your own, which does defeat the purpose of connect doing it for you. Although, the fixes to get same preformances aren't difficult, and those fixes would make other things in your app more preformant. So there's that.

Unless you're REALLY into getting optimal preformance, I don't think the rerenders you loose out on are going to really slow your app down.

I think if it comes down to improving your rerenders your going to use useMemo anyways.

Thread Thread
leob profile image
leob

Right, so if you grasp how it works then without too much difficulty you can obtain virtually the same performance, and you're learning something useful in the process (you'd gain a deeper understanding) ... if I'd ever attempt this stuff then I'd re-read that article first!

Thread Thread
jimmymcbride profile image
Jimmy McBride Author

Definitely. useMemo is a great hook to learn too. If your into rerender optimization, check out React hook from. It does some pretty cool stuff!

Thread Thread
leob profile image
leob

Ah you mean React Hook Form? react-hook-form.com/

Thread Thread
jimmymcbride profile image
Jimmy McBride Author

Oh, yeah!

Collapse
jimmymcbride profile image
Jimmy McBride Author

I would assume that the preformance is identical. However I haven't personally run tests to find out, so I can't give you a definitive yes.

Collapse
cundy profile image
Pedro Pablo

I prefer the connect variant, your component relies on properties begin passed(as web components must be designed) and makes it reusable, on the other hand redux hooks kills this principle, make your components (normally containers components) smart and less flexible.

Collapse
taufn profile image
Taufan

I suppose with the first approach it's simple to test the component as we can mock the props. But for the second one, how do you test your component?