Understanding Redux: Beginner's guide to modern state management

Understanding Redux: Beginner's guide to modern state management

10 mins read
Oct 31, 2025
Share
editor-page-cover
Content
What is state management?
What is Redux, and why do we need it?
Master Redux.
Benefits and limitations of Redux
Main concepts of Redux
Action
Action creators
Reducer
Redux store
Getting started with Redux
Embracing Redux Toolkit: The Modern Standard
Hooks-First Integration with React
Simplified Data Fetching with RTK Query
When (and When Not) to Use Redux
Performance Considerations and Best Practices
TypeScript-First Development
Using Redux with Frameworks and SSR
Next steps
Continue reading about React and Redux

So, you know JavaScript. And you know frontend framework like React. You’re off to the races, building your amazing single-page-application and expanding it.

Over time, your React application becomes more complex, with more app components, and more data going in and out of it. Now you’re running into issues, and managing multiple simultaneous processes is turning into a headache. How do you keep it all in line?

The answer is to use Redux.

What is state management?#

State, a term from React, is an object that holds data contained within a component. It determines how a component behaves and renders. State is a central component to making dynamic pages through conditional rendering.

An easy way to grasp this concept is to understand the user interface as a function of state, meaning that a developer can change the appearance of the web application depending upon the data held by the state. Imagine you are building a to-do-list application with React.

You have a todo-item component, and you want to program the component so that when a user clicks the item, it gets crossed out. You can have a state variable called isFinished and have its value be either True or False. Depending upon the value of isFinished, the todo-item can be programmed to be crossed out.

State management is simply the management of the state of multiple user interface controls or components. As developers work on larger, more complex applications, they begin using external tools to better manage the state of their application.

To make state management easier, developers often use state management libraries that allow them to create a model of their app state, update the state of components, monitor and observe changes to the state, and read state values.

Because state can be messy to manage, especially when there are a number of dynamic components, utilizing a state management system will help your future debugging.

Some popular state management tools:

  • Redux

  • Vuex

  • Mobx

  • Apollo Link State

  • Unstated

  • Flux


What is Redux, and why do we need it?#

widget

Redux is a lightweight state management tool for JavaScript applications, released in 2015 and created by Dan Abramov and Andrew Clark.

Redux is the most popular state management solution, helping you write apps that behave in the same way, are easy to test, and can run the same in different environments (client, server, native). One of the key ways Redux does this is by making use of a redux store, such that the entire application is handled by one state object.

According to its official documentation, Redux was founded on three core principles:

  • The state of your whole application is stored in an object tree within a single store.

  • Ensure the application state is read-only and requires changes to be made by emitting a descriptive action.

  • To specify how the state tree is transformed by actions, you write pure reducer functions.

With the entire state of your application centralized in one location, each component has direct access to the state (at least without sending props to child components, or callback functions to parent components).


Master Redux.#

Educative’s Redux course teaches you how to use Redux with React and javascript so that you can develop powerful web applications.

Learn Redux


With the hooks functionality and Context API incorporated into React, some have questioned whether Redux is still necessary to build a larger react application. The answer is yes. Though you may not need it for a simple React application, you will need it when your applications become more complex. The Context API is not a replacement for Redux.

Problems with the Context API arise when your app expands. In a larger application, the order in which data moves can be important. With Redux, you can keep a record of the changes in your state and time travel back to these changes.

Furthermore, Redux is more efficient than React stand-alone because Context often forces re-renders.

Furthermore, while Context API has made it easier to pass data between components without using Redux, it’s not a state manager, which means you’re missing out on a lot of other features. Redux offers tools that make it incredibly easy for you to debug, test, and track your state.

To be sure, Redux provides scalability, easy debugging, and middlewares. It’s also important to note that Context and Redux cannot be compared in the same category, as Redux is decoupled from the UI layer and is a state management system, while Context is not.

Benefits and limitations of Redux#

  • State transfer: State is stored together in a single place called the ‘store.’ While you don’t need to store all the state variables in the ‘store,’ it’s especially important to when state is being shared by multiple components or in a more complex architecture.

    As your application grows larger, it can be increasingly difficult to identify the source of the state variables, which is why a ‘store’ is useful. It also allows you to call state data from any component easily.

  • Predictability: Redux is “a predictable state container for JavaScript apps.” Because reducers are pure functions, the same result will always be produced when a state and action are passed in. Furthermore, the slices of state are defined for you, making the data flow more predictable.

  • Maintainability: Redux provides a strict structure for how the code and state should be managed, which makes the architecture easy to replicate and scale for somebody who has previous experience with Redux.

  • Ease of testing and debugging: Redux makes it easy to test and debug your code since it offers powerful tools such as Redux DevTools in which you can time travel to debug, track your changes, and much more to streamline your development process.

While Redux is something that every developer should consider utilizing when developing their application, it’s not for everyone. Setting up the Redux architecture for your application can be a difficult and seemingly unnecessary process when you’re working with a small application. It may be unnecessary overhead to use Redux unless you’re scaling a large application.

Main concepts of Redux#

Naturally, using an external solution for state management means being familiar with a few rules in the development process. Redux introduces actions, action creators, reducers, and stores. Ultimately, these concepts are used to create a simple state management architecture.

widget

Action#

Action is static information about the event that initiates a state change. When you update your state with Redux, you always start with an action. Actions are in the form of Javascript objects, containing a type and an optional payload.

Action creators#

These are simple functions that help you create actions. They are functions that return action objects, and then, the returned object is sent to various reducers in the application.

Reducer#

A reducer is a pure function that takes care of inputting changes to its state by returning a new state. The reducer will take in the previous state and action as parameters and return the application state. As your app grows, your single reducer will be split off into smaller reducers that manage certain parts of the state tree.

Redux store#

The Redux store is the application state stored as objects. Whenever the store is updated, it will update the React components subscribed to it. You will have to create stores with Redux. The store has the responsibility of storing, reading, and updating state.

Getting started with Redux#

Although Redux is used with other JavaScript libraries like Angular or Vue.js, it’s most commonly used for React projects. Let’s take a look at a basic implementation of React-Redux.

import { createStore } from 'redux'
function count(state = 0, action) {
switch (action.type) {
case 'increase':
return state + 1
case 'decrease':
return state - 1
default:
return state
}
}
let store = createStore(counter)
store.subscribe(() => console.log(store.getState()))
store.dispatch({ type: 'increase' })
store.dispatch({ type: 'decrease' })
  • Line 3 - 12: This implements a reducer, a pure function with (state, action) => state signature. The function transforms the initial state into the next state based on the action.type.

  • Line 14: Creates a Redux store, which holds the state of the app. Its API is { subscribe, dispatch, getState }. The createStore is part of the Redux library.

  • Line 16: subscribe() is used to update the UI in response to state changes.

  • Line 18 - 19: An action is dispatched to mutate the internal state.

Embracing Redux Toolkit: The Modern Standard#

Since 2020, the Redux ecosystem has evolved significantly.
Today, the recommended way to write Redux logic is through Redux Toolkit (RTK) — a set of opinionated utilities that reduce boilerplate and enforce best practices by default.
In fact, the official Redux documentation now calls RTK the standard way to write Redux code.

Redux Toolkit simplifies state management by handling common setup tasks for you.
It comes with built-in support for DevTools, middleware, immutable state updates via Immer, and a clear structure that scales with your application.

Example using RTK:

import { createSlice, configureStore } from '@reduxjs/toolkit'
const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0 },
reducers: {
increment: state => { state.value += 1 },
decrement: state => { state.value -= 1 }
}
})
export const { increment, decrement } = counterSlice.actions
const store = configureStore({
reducer: {
counter: counterSlice.reducer
}
})

This approach is cleaner, easier to maintain, and scales far better than the older createStore pattern.

Hooks-First Integration with React#

Modern Redux projects now use the React-Redux hooks API instead of the older connect() function.
Hooks provide a simpler, more intuitive way to access state and dispatch actions in functional components.

Example:

import { useSelector, useDispatch } from 'react-redux'
import { increment } from './counterSlice'
function Counter() {
const count = useSelector(state => state.counter.value)
const dispatch = useDispatch()
return (
<div>
<p>Count: {count}</p>
<button onClick={() => dispatch(increment())}>Increment</button>
</div>
)
}

This hooks-based approach aligns perfectly with functional components and React 18’s rendering model.

Simplified Data Fetching with RTK Query#

One of the biggest changes in Redux best practices is how we handle server state.
Instead of manually writing thunks, reducers, and loading logic, most teams now use RTK Query, a built-in data-fetching and caching solution included with Redux Toolkit.

RTK Query automatically generates hooks for your API endpoints and handles caching, invalidation, loading states, and error handling out of the box.

Example:

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
export const api = createApi({
reducerPath: 'api',
baseQuery: fetchBaseQuery({ baseUrl: '/api' }),
endpoints: builder => ({
getPosts: builder.query({
query: () => 'posts'
})
})
})
export const { useGetPostsQuery } = api

With RTK Query, managing server data becomes almost effortless, and your Redux store remains focused on client-side state.

When (and When Not) to Use Redux#

Another important shift in the Redux ecosystem is recognizing that you don’t always need Redux.
Modern React features like Context, useReducer, and Server Components have reduced the need for global state in many small or medium projects.

Redux shines when:

  • You need to manage complex, shared state across many components.

  • You want predictable state transitions and powerful developer tooling.

  • You require time-travel debugging, middleware, or caching strategies.

  • Your app’s state logic is expected to grow over time.

In simpler cases, Context or local state might be enough.
Understanding when Redux is the right tool is just as important as knowing how to use it.

Performance Considerations and Best Practices#

The conversation around Redux performance has evolved.
While the original blog warned about React Context causing re-renders, the modern approach emphasizes selector optimization and subscription granularity.

Modern best practices:

  • React-Redux minimizes re-renders automatically using fine-grained subscriptions and memoized selectors.

  • Use createSelector from the Reselect library to memoize derived data.

  • Combine selectors with useSelector so components only re-render when relevant parts of the state change.

With these patterns, Redux applications remain highly performant even at scale.

TypeScript-First Development#

Today, TypeScript is the default for most new Redux projects.
Redux Toolkit is written in TypeScript and provides excellent type inference, making it easier to build safe, maintainable logic.

Example of typed hooks:

import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
import type { RootState, AppDispatch } from './store'
export const useAppDispatch: () => AppDispatch = useDispatch
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector

This ensures strong typing across your entire application — from state access to action dispatching.

Using Redux with Frameworks and SSR#

If you’re building with frameworks like Next.js, Redux now has excellent support for server-side rendering (SSR) and hydration.
Modern patterns involve preloading state on the server and hydrating the Redux store on the client for seamless performance and SEO benefits.

The official Redux Toolkit documentation includes dedicated examples for Next.js and Remix, making it easy to integrate Redux into full-stack React applications.

Next steps#

Now, you might feel ready to begin testing the waters with Redux, but don’t get ahead of yourself. Redux has a pretty big learning curve initially. It’s tougher to pick up on your own.

To help you along the way, Educative has created the Understanding Redux course, which is designed to give you a primer on the basics of Redux. It’s an interactive course, with plenty of coding challenges to make learning Redux not just easier, but more fun.

By the end, you’ll build skypey, a modern messaging app to bring your JS, React, and Redux skills altogether.


Written By:
Aaron Xie