Introduction to Redux
What is Redux?
Redux is a predictable state container for JavaScript apps. It helps you manage the state of your application in a predictable manner, making it easy to test and debug. Redux is often used with libraries like React and Angular to build user interfaces.
Why Use Redux?
In a complex application, managing state can become messy and hard to debug. This is where Redux comes in. Redux provides a single source of truth for your state, making it easier to manage and reason about. It also provides great developer tools for going back in time and understanding exactly what is happening in your app at any given moment.
Redux Principles
Redux is based on three fundamental principles:
Single source of truth: The state of your whole application is stored in a single object tree within a single store. This makes it easier to keep track of changes over time and debug or inspect the application.
State is read-only: The only way to change the state is to emit an action, an object describing what happened. This ensures that neither the views nor the network callbacks will ever write directly to the state.
Changes are made with pure functions: To specify how the state tree is transformed by actions, you write pure reducers. Reducers are just pure functions that take the previous state and an action, and return the next state.
Core Concepts of Redux
In Redux, the state of your whole application is stored in an object tree inside a single store. The only way to change the state tree is to emit an action, a plain object describing what happened. To tie state and actions together, we write a function called a reducer.
Actions
Actions are payloads of information that send data from your application to your Redux store. They are the only source of information for the store. You send them to the store using store.dispatch()
.
Here's an example action which represents adding a new todo item:
{
type: 'ADD_TODO',
text: 'Build my first Redux app'
}
Reducers
Actions describe the fact that something happened, but don't specify how the application's state changes in response. This is the job of reducers.
A reducer is a pure function that takes the current state and an action, and returns the next state.
(previousState, action) => newState
It's important to return a new state object, instead of mutating the previous state. You can start with a simple reducer as below:
function todoApp(state = initialState, action) {
switch (action.type) {
case 'ADD_TODO':
return Object.assign({}, state, {
todos: [
...state.todos,
{
text: action.text,
completed: false
}
]
});
default:
return state;
}
}
Store
The Store is the object that brings together the state, actions and reducers. It has the following responsibilities:
- Holds application state;
- Allows access to state via
getState()
; - Allows state to be updated via
dispatch(action)
; - Registers listeners via
subscribe(listener)
; - Handles unregistering of listeners via the function returned by
subscribe(listener)
.
Here's how you might create a store with createStore()
:
import { createStore } from 'redux';
import todoApp from './reducers';
let store = createStore(todoApp);
Conclusion
Redux is a powerful tool for managing your application's state. It provides a single source of truth and great developer tools. By understanding its core concepts, you can start to leverage Redux in your own applications.