Using the React-Redux Hooks API to Manipulate Store State
Tags: react, redux, javascript, webdev
Published: 2021-01-25 01:48:45

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**


With Redux, we can use it to store data in a central location in our JavaScript app. It can work alone and it’s also a popular state management solution for React apps when combined with React-Redux.

In this article, we’ll look at how to use the `useDispatch` and `useStore` hooks in the React-Redux hooks API, and also look at performance and stale state issues.

### `useDispatch`

We can use the `useDispatch` hook to get the `dispatch` function to dispatch actions to the store.

For example, we use `useDispatch` as follows:

```
import React from "react";
import ReactDOM from "react-dom";
import { Provider, useSelector, useDispatch } from "react-redux";
import { createStore } from "redux";

function count(state = 0, action) {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    case "DECREMENT":
      return state - 1;
    default:
      return state;
  }
}

const store = createStore(count);

function App() {
  const count = useSelector(state => state);
  const dispatch = useDispatch();
  return (
    <div className="App">
      <button onClick={() => dispatch({ type: "INCREMENT" })}>Increment</button>
      <button onClick={() => dispatch({ type: "DECREMENT" })}>Decrement</button>
      <p>{count}</p>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  rootElement
);
```

In the code above, we called `useDispatch` in `App` to get the `dispatch` function so that we can dispatch actions from the store.

Then we create functions that call `dispatch` to pass into the `onClick` prop.

### `useStore`

We can use the `useStore` hook to get the reference to the Redux store. It’s the same one that we passed into the `Provider` component.

This shouldn’t be used frequently since we aren’t supposed to access the store directly within a React app since it doesn’t update according to the React update cycle.

### Stale Props and “Zombie Children”

Stale props mean that a selector function relies on a component’s props to extract data, a parent component would re-render and pass down new props as a result of an action, but the component’s selector functions execute before the component has a chance to re-render with those new props.

This causes outdated data to be displayed. in the child component or an error being thrown.

“Zombie child” refers to the cases where multiple nested connected components are mounted ina first pass, causing a child component to subscribe to the store before its parent. Then an action is dispatched that deletes data from the store. The parent component would stop rendering the child as a result.

Because the child subscribed to the store first, its subscription runs before the parent stops render. When it reads a value based on props, the data no longer exists. Then an error may be thrown when the extraction logic doesn’t check for the case of the missing data.

Therefore, we should rely on props in our selector function for extracting data.

`connect` adds the necessary subscription to the context provider and delays evaluating child subscriptions until the connected component has re-rendered. Putting a connected component in the component tree just above the component using `useSelector` will prevent the issues above.

![](https://cdn-images-1.medium.com/max/800/0*gWskHSYDoZE_b6lo)Photo by [Ezra Jeffrey-Comeau](https://unsplash.com/@emcomeau?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)

### Performance

`useSelector` will do a reference equality comparison of the selected value when running the selector function after an action is dispatched.

It’ll only re-render if the previous state is different from the current state. `connect` and `useSelector` doesn’t prevent the component from re-rendering because of its parent re-rendering.

To stop parent re-rendering from re-rendering the child, we can use memoization to prevent that.

For example, we can write the following:

```
import React from "react";
import ReactDOM from "react-dom";
import { Provider, useSelector, useDispatch } from "react-redux";
import { createStore } from "redux";

function count(state = 0, action) {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    case "DECREMENT":
      return state - 1;
    default:
      return state;
  }
}

const store = createStore(count);

function App() {
  const count = useSelector(state => state);
  const dispatch = useDispatch();
  return (
    <div className="App">
      <button onClick={() => dispatch({ type: "INCREMENT" })}>Increment</button>
      <button onClick={() => dispatch({ type: "DECREMENT" })}>Decrement</button>
      <p>{count}</p>
    </div>
  );
}

App = React.memo(App);

const rootElement = document.getElementById("root");
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  rootElement
);
```

In the code above, we added the `React.memo` call as follows:

```
App = React.memo(App);
```

to cache existing results and preventing re-render if the state remains the same.

### Conclusion

We can use the `useDispatch` hook to get the `dispatch` function to update the store’s state.

There’s also a `useStore` hook to get a reference of the Redux store in our React components.

However, we shouldn’t access the store directly with `useStore` since we’re supposed to use `useSelector` to get the latest state from the store and use `useDispatch` to dispatch actions.

Also, we have to be aware of stale props from parent components and child components that have been removed because of state changes throwing errors and displaying incorrect data.

We should also memoize the state of components to cache them so that they don’t have to re-render when nothing changed.