Stop Asking if React Hooks Replace Redux

Many colleagues have been asking me similar questions:

“If we use hooks in the project, do we also need Redux?”

“Will React Hooks make Redux too outdated? Can I use Hooks to do everything Redux does?”

A Google search shows that people ask these questions all the time.

“Will React Hooks replace Redux?” The short answer is “not necessarily”.

A more nuanced but polite answer is “Well, it depends on the type of project you’re working on.”

The answer I prefer to tell you is “I’m not sure you know what you’re talking about”. There are several reasons why “React Hooks will replace Redux” is an inherently flawed question. First of all:

Redux has always been optional

Dan Abramov (one of the creators of Redux) wrote an article “You Might Not Need Redux” that shows that if You don’t Need to use it, You don’t Need to replace anything.

Redux is a JavaScript library, and if you use React (another JavaScript library), you’ll need to load a React-Redux JavaScript library in your application to use Redux. Using dependent libraries in a project increases the packaging volume, which increases the load time of your application. For this reason, you shouldn’t use libraries like jQuery, Redux, MobX (another state management library), or even React unless you have a clear reason to use them.

When people ask “Do hooks replace Redux?” they often seem to feel that their React app needs to use one of them. Application that is not the case, if you are writing didn’t have a lot of state needs to be stored, or the components of the structure is simple, you can avoid excessive prop, and on the basis of the characteristics of the React itself provide you enough for the control of the state, with or without hooks, these situations using state management, there is no much meaning.

Even if you do have a lot of states, or have the React component structure twisted and forked like an old tree root, you still don’t need a state management library. Prop passing can be cumbersome, but React gives you a lot of state management options, and hooks will definitely help you organize state well. Redux is a lightweight library, but its setup is complex, increases packaging volume, and has many trade-offs. There are many reasons why you should choose not to use it in your projects, and they are very compelling.

You don’t always need Redux, which means there are still plenty of reasons to use it. If your project uses Redux from the start, it’s probably a good reason to do so, whether or not it does: organization (predictability of application state, single data flow, useful in complex applications), middleware, Redux’s powerful development tools, and debugging capabilities. If you have a reason to use Redux, it will not be rendered invalid by React Hooks. If you needed Redux before, you still need it now. This is because:

React Hooks and Redux do not attempt to solve the same problem

Redux is a state management library. Hooks are part of a recent update to React that allow your function components to do what class components do.

So not using a class component to write React applications suddenly makes the state manager library obsolete?

Of course not!

React Hooks were developed for these three reasons:

  • It is difficult to reuse logic between class components
  • The life cycle often contains some inexplicable irrelevant logic
  • Class components are difficult for machines and humans to understand

Note that none of these reasons are directly motivated to do something related to state management.

Having said that, React Hooks do provide some options for managing application state. The useState, useReducer, and useContext methods, in particular, provide new ways to maintain your state that have proven to be better and more methodical than the options previously offered by React.

But these hooks aren’t new or magic, and they don’t make state management obsolete, because the truth is:

React Hooks don’t make your app do something it couldn’t do before

That’s right, you can now write function components that do things that you could only do with class components, but they don’t do things that class components can’t do, except the ability to better organize and reuse code. They don’t necessarily make your app better, they make the developer’s experience better.

UseState and useReducer are just methods to manage component state, and they work the same as this.state and this.setState for similar components. You still need to pass your props.

UseContext is considered a nail in the Redux board because it lets you share application state between components without passing it through prop, but it doesn’t really do anything new either. The Context API is now part of React, and useContext simply lets you use the context without the

package. And some developers use context to manage the state of the entire application, which is not what context was designed for. It can be seen from the document that:

Context is designed to share data that can be considered “global” for a tree of React components, such as the current authenticated user, theme, or preferred language.

Context is designed to share data and can be considered “global” to the React component tree, such as the current authorized user, topic, or preferred language.

In other words, things that aren’t expected to update very often.

The document also recommends using context sparingly because “it makes components difficult to reuse.” They also warn developers that the context can easily trigger unnecessary repeated rendering if the developer is not careful.

I have seen projects successfully use React Context to manage application state. It is possible and an option. But state management is not exactly what context is designed to do, and Redux and other state management libraries are designed to handle that specific purpose.

Also, React Hooks are by no means the death of Redux, because if you take a look at the react-Redux documentation recently updated, you’ll see:

React-redux also has hooks of its own

Yes, React Hooks are helping react-Redux reactivate and remove some of its pain points, far from the word “replace”.

I took a closer look at React-Redux in another article, and here are the highlights. Before hooks, you must define mapStateToProps and mapDispatchToProps, and wrap your component with connect to create a higher-order component that will pass the Dispatch method and part of the Redux stored state, These are the states that you specify in the mapping function to pass to the component as props.

Let’s take a look at a very simple example of a counter application (too simple to even need Redux, but mainly to show some information). Let’s assume that we’ve defined both Redux Store and Increment and Decrement action Creators (the full source code is here).

import React from 'react';
import {connect} from 'react-redux';
import * as actions from '.. /actions/actions';

class App extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    const {count, increment, decrement} = this.props;

    return (
      <div>
        <h1>The count is {count}</h1>
        <button onClick={()= > increment(count)}>+</button>
        <button onClick={()= > decrement(count)}>-</button>
      </div>); }}const mapStateToProps = store= > ({
  count: store.count
});

const mapDispatchToProps = dispatch= > ({
  increment: count= > dispatch(actions.increment(count)),
  decrement: count= > dispatch(actions.decrement(count))
});

export default connect(mapStateToProps, mapDispatchToProps)(App);
Copy the code

How annoying! Wouldn’t it be friendlier if we didn’t have to wrap the component into a higher-order component and just let the component fetch the value of the Redux Store? Yes, that’s where hooks come in. Hooks are for reusing code and eliminating “nested hell” due to higher-order components. Here is an identical component, converted into a function component using react-redux hooks.

import React from 'react';
import * as actions from '.. /actions/actions';
import {useSelector, useDispatch} from 'react-redux';

const App = (a)= > {
  const dispatch = useDispatch();
  const count = useSelector(store= > store.count);

  return (
    <div>
      <h1>The count is {count}</h1>
      <button onClick={()= > dispatch(actions.increment(count))}>+</button>
      <button onClick={()= > dispatch(actions.decrement(count))}>-</button>
    </div>
  );
}

export default App;
Copy the code

Isn’t it beautiful? In short, useSelector lets you save some of the Redux Store values to your component. UseDispatch is simpler, it simply provides you with a Dispatch function that you can use to send status updates to the Redux store. Best of all, you no longer need to write ugly mapping functions and wrap components in connect functions. Now, everything is nicely contained in your component, which is more concise, therefore easier to read, and more organized. The point is:

There is no need to compare React Hooks to Redux

There is no doubt that the two technologies complement each other well. React Hooks don’t replace Redux, they just give you a new and better way to organize your React application. If you eventually decide to use Redux to manage state, this will allow you to write better connected components.

So stop asking “Will React Hooks replace Redux?” .

Instead, start asking yourself, “What kind of app am I making? What kind of state management do I need? Is Redux ok, or is it overused? Can hooks be used, or should class components be used? If I decide to use Redux and React Hooks (or MobX and React Hooks, or Redux and jQuery, not React — all valid choices, depending on what you’re doing), how do I make these technologies complementary and compatible?” .