https://github.com/thetallprogrammer/redux-example
A small redux example I got from a youtube tutorial, I expanded on it by using typescript and created a diagram for better understanding.
https://github.com/thetallprogrammer/redux-example
Last synced: 3 months ago
JSON representation
A small redux example I got from a youtube tutorial, I expanded on it by using typescript and created a diagram for better understanding.
- Host: GitHub
- URL: https://github.com/thetallprogrammer/redux-example
- Owner: TheTallProgrammer
- Created: 2025-09-20T20:37:30.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2025-09-20T21:10:01.000Z (4 months ago)
- Last Synced: 2025-09-20T22:20:09.756Z (4 months ago)
- Language: TypeScript
- Size: 4.08 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Understanding Redux: A Comprehensive Guide
This documentation serves as a practical reference for Redux concepts, designed for future project use and to assist anyone seeking clarity on state management in JavaScript applications.
-----
## What is Redux?
**Redux** is a **predictable state container for JavaScript apps**, most commonly used with React. Imagine it as a **centralized warehouse** for all the data (the "state") your application needs. This makes it significantly easier to manage and access that data consistently from any component within your application.

### The Core Principle: Unidirectional Data Flow
At its heart, Redux operates on a simple, **one-way data flow**. This fundamental principle ensures predictability and makes debugging easier. The flow involves three main parts: the Store, Actions, and Reducers.
### 1\. The Store
The **Store** is a single, immutable JavaScript object that holds the entire state of your application. It's the **"single source of truth"** for your application's data. You'll only ever have one Redux store in your application.
### 2\. Actions
When you want to change the state, you can't modify it directly. Instead, you **dispatch an Action**. An action is a plain JavaScript object that **describes *what happened***. Think of it as sending a formal request or a "memo" to the store, indicating an intent to change the state.
**Example Action to add a movie:**
```json
{
"type": "movies/addMovie",
"payload": "Transformers"
}
```
### 3\. Reducers
A **Reducer** is a **pure function** that receives the current `state` and an `action`. Its sole responsibility is to decide how to update the state based on that action and return a **brand new state object**. It's called a "reducer" because it takes all incoming actions and "reduces" them down to a single new state. Crucially, reducers must never mutate the original state directly; they must always return a new copy.
-----
### The Redux Data Flow Cycle:
The entire process follows a clear cycle:
1. An event happens in your UI (e.g., a button click, an API response).
2. Your UI **dispatches an Action** describing the event.
3. The **Store** passes the current `state` and the `action` to a **Reducer**.
4. The **Reducer** computes and returns a **brand new state object**.
5. The **Store** updates itself with this new state.
6. Any UI components subscribed to the relevant parts of the state automatically **re-render** to reflect the changes.
This is better visualized in the official Redux data flow diagram:
-----
## The Example Project: Movie Management with Redux Toolkit
This project demonstrates a simple movie management application, originally derived from a tutorial ([YouTube Link](https://www.youtube.com/watch?v=QgK_-G-hWeA&t=1246s)). Its primary purpose is to illustrate **state management across multiple components**, where Redux (specifically Redux Toolkit) proves invaluable.
While the original tutorial utilized JavaScript, this implementation has been converted to **TypeScript** for enhanced type safety and adherence to modern industry standards. Additionally, the styling has been customized.
Here's a detailed, step-by-step breakdown of the data flow when a new movie is added:

### The Movie Addition Process: Step-by-Step
#### 1\. User Interaction (in `MovieInput.jsx`)
* A user types a movie title, like "Transformers," into the `` field and clicks the "Add Movie" button.
* The button's `onClick={handleAddMovie}` event is triggered.
* Inside `handleAddMovie`, the `dispatch` function is called with the `addMovie()` action creator (from your slice). The current value of the input (`newMovie` state) is passed as the argument.
```javascript
// This function call initiates the Redux cycle
dispatch(addMovie("Transformers"));
```
#### 2\. The Action is Created and Dispatched
* The `addMovie("Transformers")` action creator generates a **plain JavaScript object**. Redux Toolkit automatically combines the `name` from your slice ("movies") with the reducer function name ("addMovie") to create the unique **action type**.
* The dispatched action object looks like this:
```json
{
"type": "movies/addMovie",
"payload": "Transformers"
}
```
* This action object is then sent to the Redux store via `dispatch`.
#### 3\. The Store and Root Reducer (in `store.js`)
* The store receives the action. Its primary role is to pass the current application `state` and the `action` to its main **"root reducer."**
* Your `configureStore` setup defines how different parts of your global state are managed. For instance, it specifies that the `movies` property in your global state is handled by `movieReducer`.
```javascript
reducer: {
movies: movieReducer, // <-- The store maps 'movies/...' actions to this reducer
},
```
* The store, through its root reducer, inspects the action type (`'movies/addMovie'`) and intelligently forwards it to the appropriate `movieReducer`.
#### 4\. The Slice Reducer Executes (in `movieSlice.js`)
* The `movieReducer` from your `movieSlice` takes over. It examines the `action.type` and executes the corresponding function defined in its `reducers` object.
* The `addMovie` function within `movieSlice` is executed:
* **`state`** here refers *only* to the current `movies` slice of the global state (e.g., `{ movies: [...] }`), not the entire app state.
* **`action`** is the action object from Step 2.
```javascript
addMovie: (state, action) => {
// action.payload is "Transformers"
const newMovie: Movie = {
id: state.movies[state.movies.length - 1].id + 1, // this state.movies
// is saying (state.movies).movies, state = (state.movies) in this scope
title: action.payload // The movie title from the action
}
// Redux Toolkit's Immer allows "mutating" logic,
// which safely produces an immutable new state.
state.movies.push(newMovie);
},
```
*(Note: The `id` generation has been updated to `Date.now()` for robust uniqueness, and `newMovie` is pushed instead of `action.payload` to ensure the correct object structure.)*
#### 5\. The State is Updated
* Redux Toolkit leverages a library called **Immer** behind the scenes. This powerful tool allows you to write state-updating logic that looks like it's directly "mutating" the state (e.g., `state.movies.push(...)`). Immer then safely translates these mutations into **immutable updates**, returning a brand new state object.
* The `movieSlice` returns a new state object specifically for the `movies` slice.
* The root reducer then assembles this new slice with any other (unchanged) slices to form the complete, new **global state object**.
* The store is now updated and holds this new, final application state.
#### 6\. The UI Re-Renders
* Any React components in your application that are **subscribed** to the Redux store (typically using the `useSelector` hook to extract data like the `movies` list) will be notified of the state change.
* `useSelector` efficiently compares the new data with the previously selected data. If the data has changed, the component will automatically **re-render** to display the updated information, ensuring your UI always reflects the latest state.
-----
## Getting Started
To explore this application and see Redux in action:
1. **Clone the repository** to your local machine.
2. Navigate to the project directory in your terminal.
3. Install dependencies: `npm install`
4. Start the development server: `npm run dev`
Feel free to experiment with and extend this project. Its core purpose is to inform and assist in understanding Redux, building upon the foundational concepts from the original tutorial.