Understanding the Core Concepts in Redux: Actions, Reducers, Store, Dispatch, and Selectors

Understanding the Core Concepts in Redux: Actions, Reducers, Store, Dispatch, and Selectors

Featured on Hashnode

Redux is a powerful state management library often used with React to manage the application state in a predictable and consistent manner. It revolves around a few key concepts: Actions, Reducers, Store, Dispatch, and Selectors. Each of these plays a distinct role in how your application handles and accesses state. In this blog post, we will break down these concepts and understand how they interact with each other.

1. Actions: The Messengers of Intent

In Redux, actions are plain JavaScript objects that represent an intention to change the state. Think of them as messengers that carry information from your application’s UI to the Redux store. An action must have a type property, which is a string that describes the action's purpose. It can also include a payload that carries additional data required to update the state.

Example:

{
  type: 'ADD_TODO',
  payload: {
    id: 1,
    text: 'Learn Redux'
  }
}

In this example, the action describes an intention to add a new to-do item with the text "Learn Redux". The type property is mandatory, while the payload provides the details of the to-do item.

2. Reducers: The State Changers

Reducers are pure functions that define how the state should change in response to an action. A reducer takes two arguments: the current state and the action. It processes the action and returns a new state. Since reducers are pure functions, they do not modify the existing state but instead return a new state object.

Example:

const todoReducer = (state = [], action) => {
  switch (action.type) {
    case 'ADD_TODO':
      return [...state, action.payload];
    default:
      return state;
  }
};

In this example, the todoReducer handles the ADD_TODO action by returning a new state that includes the new to-do item. If the action type doesn't match any case, the reducer simply returns the current state.

3. Store: The State Container

The store is the centralized place where the entire state of your application is stored. It’s created using the createStore function, which takes the root reducer as an argument. The store is responsible for holding the state, allowing access to the state, and dispatching actions to update the state.

Example:

import { createStore } from 'redux';

const store = createStore(todoReducer);

Here, we create a Redux store using the todoReducer. This store will now hold the state managed by that reducer and provide methods to interact with that state.

4. Dispatch: The Trigger

Dispatch is a method provided by the store that allows you to send an action to the Redux store. When you dispatch an action, it triggers the corresponding reducer to process the action and update the state accordingly. Dispatching is the way to trigger state changes in Redux.

Example:

store.dispatch({
  type: 'ADD_TODO',
  payload: {
    id: 1,
    text: 'Learn Redux'
  }
});

In this example, the dispatch method sends the ADD_TODO action to the Redux store. This action is then handled by the reducer, which updates the state with the new to-do item.

5. Selectors: The Data Extractors

Selectors are functions that retrieve specific pieces of data from the Redux state. They encapsulate the logic for accessing the state, making it easier to reuse and manage. Selectors help you extract and compute derived data from the state, ensuring that your components receive only the data they need.

Example:

const selectTodos = (state) => state.todos;

const todos = selectTodos(store.getState());

In this example, selectTodos is a selector function that extracts the list of to-dos from the state. By using selectors, you can keep your state access logic organized and reusable.

Conclusion

Understanding the roles of actions, reducers, store, dispatch, and selectors is crucial to effectively managing state in a Redux application. Actions describe the events or changes that should happen in your application. Reducers define how the state should change in response to those actions. The store is the central place where the state is kept, and dispatch is the method used to trigger those changes. Finally, selectors help you retrieve specific data from the state, making your code more modular and easier to maintain.

By mastering these core concepts, you can leverage Redux to build applications with a predictable state management flow, ensuring that your app behaves consistently as it grows in complexity.