{"id":31692574,"url":"https://github.com/thetallprogrammer/redux-example","last_synced_at":"2025-10-08T14:54:15.520Z","repository":{"id":315810306,"uuid":"1060903352","full_name":"TheTallProgrammer/Redux-Example","owner":"TheTallProgrammer","description":"A small redux example I got from a youtube tutorial, I expanded on it by using typescript and created a diagram for better understanding.","archived":false,"fork":false,"pushed_at":"2025-09-20T21:10:01.000Z","size":4277,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-20T22:20:09.756Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TheTallProgrammer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-20T20:37:30.000Z","updated_at":"2025-09-20T21:10:05.000Z","dependencies_parsed_at":"2025-09-20T22:20:12.125Z","dependency_job_id":"0640f189-8da7-4c81-96c3-caf3e4adf3bc","html_url":"https://github.com/TheTallProgrammer/Redux-Example","commit_stats":null,"previous_names":["thetallprogrammer/redux-example"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/TheTallProgrammer/Redux-Example","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheTallProgrammer%2FRedux-Example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheTallProgrammer%2FRedux-Example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheTallProgrammer%2FRedux-Example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheTallProgrammer%2FRedux-Example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TheTallProgrammer","download_url":"https://codeload.github.com/TheTallProgrammer/Redux-Example/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheTallProgrammer%2FRedux-Example/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278963840,"owners_count":26076543,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-08T14:54:05.885Z","updated_at":"2025-10-08T14:54:15.511Z","avatar_url":"https://github.com/TheTallProgrammer.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Understanding Redux: A Comprehensive Guide\n\nThis 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.\n\n-----\n\n## What is Redux?\n\n**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.\n\n![redux official diagram](/public/docs/ReduxDataFlowDiagram.gif)\n\n### The Core Principle: Unidirectional Data Flow\n\nAt 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.\n\n### 1\\. The Store\n\nThe **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.\n\n### 2\\. Actions\n\nWhen 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.\n\n**Example Action to add a movie:**\n\n```json\n{\n  \"type\": \"movies/addMovie\",\n  \"payload\": \"Transformers\"\n}\n```\n\n### 3\\. Reducers\n\nA **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.\n\n-----\n\n### The Redux Data Flow Cycle:\n\nThe entire process follows a clear cycle:\n\n1.  An event happens in your UI (e.g., a button click, an API response).\n2.  Your UI **dispatches an Action** describing the event.\n3.  The **Store** passes the current `state` and the `action` to a **Reducer**.\n4.  The **Reducer** computes and returns a **brand new state object**.\n5.  The **Store** updates itself with this new state.\n6.  Any UI components subscribed to the relevant parts of the state automatically **re-render** to reflect the changes.\n\nThis is better visualized in the official Redux data flow diagram:\n\n-----\n\n## The Example Project: Movie Management with Redux Toolkit\n\nThis project demonstrates a simple movie management application, originally derived from a tutorial ([YouTube Link](https://www.youtube.com/watch?v=QgK_-G-hWeA\u0026t=1246s)). Its primary purpose is to illustrate **state management across multiple components**, where Redux (specifically Redux Toolkit) proves invaluable.\n\nWhile 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.\n\nHere's a detailed, step-by-step breakdown of the data flow when a new movie is added:\n![diagram](/public/docs/Redux%20Movie%20Example.png)\n\n### The Movie Addition Process: Step-by-Step\n\n#### 1\\. User Interaction (in `MovieInput.jsx`)\n\n  * A user types a movie title, like \"Transformers,\" into the `\u003cinput\u003e` field and clicks the \"Add Movie\" button.\n  * The button's `onClick={handleAddMovie}` event is triggered.\n  * 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.\n    ```javascript\n    // This function call initiates the Redux cycle\n    dispatch(addMovie(\"Transformers\"));\n    ```\n\n#### 2\\. The Action is Created and Dispatched\n  * 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**.\n  * The dispatched action object looks like this:\n    ```json\n    {\n      \"type\": \"movies/addMovie\",\n      \"payload\": \"Transformers\"\n    }\n    ```\n  * This action object is then sent to the Redux store via `dispatch`.\n\n#### 3\\. The Store and Root Reducer (in `store.js`)\n\n  * The store receives the action. Its primary role is to pass the current application `state` and the `action` to its main **\"root reducer.\"**\n  * 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`.\n    ```javascript\n    reducer: { \n        movies: movieReducer, // \u003c-- The store maps 'movies/...' actions to this reducer\n    },\n    ```\n  * The store, through its root reducer, inspects the action type (`'movies/addMovie'`) and intelligently forwards it to the appropriate `movieReducer`.\n\n#### 4\\. The Slice Reducer Executes (in `movieSlice.js`)\n\n  * The `movieReducer` from your `movieSlice` takes over. It examines the `action.type` and executes the corresponding function defined in its `reducers` object.\n  * The `addMovie` function within `movieSlice` is executed:\n      * **`state`** here refers *only* to the current `movies` slice of the global state (e.g., `{ movies: [...] }`), not the entire app state.\n      * **`action`** is the action object from Step 2.\n    \u003c!-- end list --\u003e\n    ```javascript\n    addMovie: (state, action) =\u003e {\n        // action.payload is \"Transformers\"\n        const newMovie: Movie = {\n            id: state.movies[state.movies.length - 1].id + 1, // this state.movies \n            // is saying (state.movies).movies, state = (state.movies) in this scope\n            title: action.payload // The movie title from the action\n        }\n        // Redux Toolkit's Immer allows \"mutating\" logic,\n        // which safely produces an immutable new state.\n        state.movies.push(newMovie); \n    },\n    ```\n    *(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.)*\n\n#### 5\\. The State is Updated\n\n  * 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.\n  * The `movieSlice` returns a new state object specifically for the `movies` slice.\n  * The root reducer then assembles this new slice with any other (unchanged) slices to form the complete, new **global state object**.\n  * The store is now updated and holds this new, final application state.\n\n#### 6\\. The UI Re-Renders\n\n  * 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.\n  * `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.\n\n-----\n\n## Getting Started\n\nTo explore this application and see Redux in action:\n\n1.  **Clone the repository** to your local machine.\n2.  Navigate to the project directory in your terminal.\n3.  Install dependencies: `npm install`\n4.  Start the development server: `npm run dev`\n\nFeel 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.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthetallprogrammer%2Fredux-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthetallprogrammer%2Fredux-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthetallprogrammer%2Fredux-example/lists"}