Revolutionize Your React App with Redux: A Beginner's Guide to Simplifying State Management(PART 2)

Abdulsalaam Noibi - Apr 12 '23 - - Dev Community

Here is a link to PART 1

Creating a Reducer Function to handle each Action type and Update the Store Accordingly

Reducers are called reducers because they are used in the reduce() function, which is used to reduce an array of values to a single value. In Redux, reducers are used to reduce the current state of the store to a new state based on the action that is dispatched.

Creating a Reducer Function

To create a reducer function in Redux, you need to follow a few conventions. First, the function should take two arguments: the current state and an action. Second, the function should return a new state based on the action that is dispatched.

Here's an example of a simple reducer function:

const initialState = {
  count: 0
};

function counterReducer(state = initialState, action) {
  switch (action. Type) {
    case 'INCREMENT':
      return { count: state. Count + 1 };
    case 'DECREMENT':
      return { count: state. Count - 1 };
    default:
      return state;
  }
}

Enter fullscreen mode Exit fullscreen mode

In the above code snippet example, we're creating a reducer function called counterReducer.

The function takes two arguments: the current state (which is initialized to an object with a count property set to 0) and an action.

The function returns a new state based on the action that is dispatched.

The reducer function uses a switch statement to handle different action types. In this example, we're handling two action types: INCREMENT and DECREMENT.

When the INCREMENT action is dispatched, the function returns a new state object with the count property incremented by 1. Similarly, when the DECREMENT action is dispatched, the function returns a new state object with the count property decremented by 1. If any other action is dispatched, the function simply returns the current state.

Combining Reducers

In larger applications, multiple reducers may handle different parts of the state. To combine these reducers into a single reducer function that can be passed to the store, Redux provides a combineReducers() function.

Here's an example of how to use combineReducers() to combine multiple reducers:

import { combineReducers } from 'redux';

const counterInitialState = {
  count: 0
};

function counterReducer(state = counterInitialState, action) {
  switch (action. Type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    default:
      return state;
  }
}

const todosInitialState = {
  items: []
};

function todosReducer(state = todosInitialState, action) {
  switch (action. Type) {
    case 'ADD_TODO':
      return { items: [...state. Items, action.payload] };
    case 'REMOVE_TODO':
      return { items: state.items.filter(todo => todo.id !== action.payload) };
    default:
      return state;
  }
}

const rootReducer = combineReducers({
counter: counterReducer,
todos: todosReducer
});

Enter fullscreen mode Exit fullscreen mode

In this example, we're creating two reducers: counterReducer and todosReducer. Each reducer handles a different part of the state.

We're then using combineReducers() to combine these reducers into a single reducer function called rootReducer. The resulting state object will have two properties: counter and todos, which correspond to the state handled by each reducer.

Using the Reducer in a React Component

Once you've created a reducer function and combined it with other reducers using combineReducers(), you can use the resulting reducer function in a React component using the useReducer() hook.

Here's an example of how to use the useReducer() hook to manage state in a React component:

import React, { useReducer } from 'react';

function Counter() {
  const [state, dispatch] = useReducer(counterReducer, { count: 0 });

  function handleIncrement() {
    dispatch({ type: 'INCREMENT' });
  }

  function handleDecrement() {
    dispatch({ type: 'DECREMENT' });
  }

  return (
    <div>
      <h1>Count: {state. Count}</h1>
      <button onClick={handleIncrement}>Increment</button>
      <button onClick={handleDecrement}>Decrement</button>
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

In this example, we're using the useReducer() hook to manage state in a component called Counter. We're passing the counterReducer function as the first argument to useReducer(), along with the initial state of the count (which is an object with a count property set to 0).

We're then defining two functions (handleIncrement() and handleDecrement()) that dispatch the INCREMENT and DECREMENT actions, respectively.

Finally, we're rendering the current count and two buttons that trigger the corresponding actions when clicked.

Creating a selector function to extract a specific piece of data from the store

In Redux, selectors are functions that are used to extract data from the state in a structured way. Selectors are especially useful when the state is complex or when you want to derive new data from the state.

In this section, we'll explain how to create and use selectors in a React application that uses Redux for state management.

Creating a Selector Function

To create a selector function, you can use the createSelector() function from the reselect library. The createSelector() function takes one or more input selectors and a transform function, and returns a memorized selector function.

Here's an example of how to create a selector function that extracts the current count from the state:

import { createSelector } from 'reselect';

const getCount = state => state.counter.count;

export const countSelector = createSelector(
  [getCount],
  count => count
);

Enter fullscreen mode Exit fullscreen mode

In this example, we're using the createSelector() function to create a memorized selector function called countSelector.

The selector function takes an input selector called getCount, which simply extracts the count property from the counter slice of the state.

The transform function takes the count as input and returns it as output. The resulting countSelector function can be used to extract the count from the state in an effective way.

Using the Selector Function in mapStateToProps()

Once you've created a selector function, you can use it in the mapStateToProps() function to pass the data to the component as props.

Here's an example of how to use the countSelector function in mapStateToProps():

import { connect } from 'react-redux';
import { countSelector } from './selectors';

function Counter({ count, dispatch }) {
  // ...
}

function mapStateToProps(state) {
  return {
    count: countSelector(state)
  };
}

export default connect(mapStateToProps)(Counter);

Enter fullscreen mode Exit fullscreen mode

In this example, we're using the connect() function to connect a component called Counter to the Redux store. We're importing the countSelector function from a file called selectors.js.

We're then defining a mapStateToProps() function that maps the count property from the state to a prop called count in the component, using the countSelector function to extract the count from the state. Finally, we're exporting the connected Counter component.

Conclusion

Selectors are a powerful tool in Redux that enable you to extract data from the state in a structured and performant way. By using the createSelector() function from the reselect library, you can create memorized selector functions that extract new data from the state or extract specific pieces of data from the state. By using selectors in conjunction with the mapStateToProps() function, you can pass the data to your React components as props and render the data in your UI.

Final Conclusion

we've discussed how Redux can be useful for managing complex state in a React application, and covered the following topics in previous sections:

  • Installing the necessary packages (redux, react-redux)
  • Creating a Redux store and initializing it with initial state
  • Creating actions and action creators to update the store
  • Creating reducers to handle the actions and update the store
  • Connecting a React component to the Redux store using the useReducer() hook.

If you want to learn more about Redux and how to use it in a React application, here are some resources you might find helpful:

THANKS FOR READING

Connect with me on Twitter

. . . . . . . . . . . . . . . . . . .
Terabox Video Player