Introduction Create a simple React App Migrating the app to Redux Flow of Data in a Redux App The Redux App - explanation Conclusion Introduction Redux is a predictable state container for JavaScript apps - as stated in Redux official documentation. When I started learning Redux, I found it difficult to comprehend the concept and implementation. I skimmed through many articles on the net but could not find a satisfactory answer. Most of the articles either explain creating apps with Redux or converting React apps with no basic code to Redux. I could not find something that explained how a working React app can be modified to use Redux with the same functionality. In this article, I have made an attempt to do exactly that. I will first explain how to create a React app that has minimal functionality of creating and deleting a list of books. This app is similar to a much-publicized ‘todo’ app. You can use it to create a Todo app also by just renaming the component and variable names. Create a simple React App With this introduction, let us dive into hands-on. Open your code editor and type ‘npx create-react-app react-redux’. You may change the name of the app from react-redux to whatever you like. Once the app creation process completes, run ‘npm start’ at your console and confirm that the app is working fine with a gently rotating React logo. Now delete all the files except those shown in the list below and create blank files which are needed: Create a directory ‘ ’ under ‘ ’ directory and create three blank files Book.js, BookForm.js, and BookList.js under the ‘ ’ directory. Once you have the files and folders, as shown above, replace the contents of the files and from the code given below, and fill the other three blank files with the code given below : components src components App.js Index.js index.js React ; ReactDOM ; App ; ReactDOM.render( import from "react" import from "react-dom" import from "./App" , document.getElementById("root") ); < /> App App.js React ; BookForm ; BookList ; { state = { : [] }; addBook = { .setState( ({ : [book, ...state.books] })); }; removeBook = { .setState({ : .state.books.filter( book.id !== id) }); }; render() { ( <h1> React to Redux</h1> <BookForm onSubmit={this.addBook} /> <BookList books={this.state.books} removeBook={this.removeBook} /> </div> ); } } export default App; import from "react" import from "./components/BookForm" import from "./components/BookList" . class App extends React Component books => book this => state books => id this books this => book return < > div Book.js React ; Book = { { book } = props; ( <div> {book.title} <button onClick={props.onDelete}>Delete</button> </div> ); }; Book; import from "react" const => props const return < > div </ > div export default BookForm.js React ; { () { (); .state = { : }; .handleChange = .handleChange.bind( ); .handleSubmit = .handleSubmit.bind( ); } handleChange(event) { { name, value } = event.target; .setState({ [name]: value }); } handleSubmit(event) { event.preventDefault(); ( .state.title) .props.onSubmit({ : .now(), : .state.title }); .setState({ : }); } render() { ( <input type="text" value={this.state.title} name="title" placeholder="Book Title" onChange={this.handleChange} /> <input type="submit" value="Submit" /> </form> ); } } export default BookForm; import from "react" . class BookForm extends React Component constructor super this title "" this this this this this this const this if this this id Date title this this title "" return < = > form onSubmit {this.handleSubmit} BookList.js React ; Book ; BookList = { ( <ul key={book.id}> <Book book={book} onDelete={() => props.removeBook(book.id)} /> </ul> ))} </div> import from "react" import from "./Book" const => props return {props.books.map(book => ( < > div ); }; export default BookList; Migrating the app to Redux Now that we have created a React app that displays a form, accepts books, displays the list and deletes any, we have a fully functional React app. Next, we will refactor the same app and see how we can use Redux to maintain the data of the app. Please remember, the purpose of this article is not to teach React but to teach how to understand and use Redux in a React application. Before proceeding further, please remember we use Redux to maintains the ‘ ’ or ‘ ’ of a React application. In this article we are going to do exactly that, moving the state of React app into Redux. state data Flow of data in a Redux App We shall try to understand the basics of Redux from the diagram above. On top right there is a box ‘ ’ in which the data flows from top component to bottom and it is held in ‘state’ of the root component. React App If you look at the bottom right diagram which shows ‘ ’, the data is not stored in the components but it is stored in a single place called ‘ ’. The data received by the components from the external interface is sent to Store using ‘ ’, and the ‘ ’ function connects the component sending the data and the Store. Redux App Store mapDispatchToProps connect The data being sent to the ‘ ’ passes through two stages viz. Store ‘ ’ and ‘ ’. The ‘ ’ is an object that specifies what type of action is needed to be done on the data and what are the other parameters for that action. Then this data is passed on to ‘ ’. is a function which performs the required action, i.e. either storing the data in the required format or creating a new set of data and replacing the old data or fetching data from the Store. This is how data is modified because in React state is not mutated. Actions Reducers Actions Reducer Reducer Now we shall briefly look at the new terms used above. The store 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) But these things are handled internally and we will not generally use those methods explicitly. Store is the place within the app where the data is stored. It is similar to ‘State’ in React Apps. Store is not accessible to the components of the App directly. Components have to connect to the Store making use of two methods. The first one is mapDispatchToProps which sends data from the components to Store and the second one is mapStateToProps which receives data from the Store into the component as prop. But these two functions need connect() which connects Store and components. When you use connect, it is followed by the name of the component being connected in parentheses. There are two more things, viz. Action and Reducer. Action is an object which specifies the inputs needed to an operation of fetching or sending data to Store. Reducer is a method which uses Action details and performs the required operation on the Store. The components of the app are segregated into ‘components’ and ‘containers’ folders. We keep presentation components i.e. components that have a user interface under components folder and the components that deal with the Store are kept under containers folder. In addition to these, we create a folder called ‘actions’ and the action objects are placed in this folder. We also create ‘reducers’ folder and keep the reducer objects under this folder. This is done so that Redux can pick up the needed components from these locations without specifying where to look for them. The Redux App Before we start refactoring our code, it is advised to make a copy of the working React app you have created just now. To begin with, let us add redux to our app by running the following commands from the terminal: npm install redux npm install react-redux First, we segregate our components depending on the functions they do and keep them separately in separate folders. For this purpose, let us create four folders with the following names. I am also specifying the file names which go under each of these folders. Only index.js is kept in the root folder. index.js components App.js Book.js containers BookForm.js BookList.js actions index.js reducers book.js index.js Now move App.js and Book.js to the folder Components and move BookForm.js and BookList.js to the containers folder. We don't have any files under actions and reducers folders which we shall be adding shortly. Follow the below and wherever it is commented '//', delete those lines and wherever it is mentioned '//add' at the end of the line, add those lines to your React App. Alternatively, you may copy the entire React App code or Redux App code from my GitHub, the link for which is given at the end of this article. I shall give a brief explanation of the changes we are making to each of the files after the code listing of each file code index.js React ; ReactDOM ; Import App “./components/App redux react-redux ./reducers root import from "react" import from "react-dom" // import App from “./App”; from "; //add import { createStore } from " "; //add import { Provider } from " "; //add import reducer from " "; //add const store = createStore(reducer); //add ReactDOM.render( <Provider store={store}> //add <App /> // remove ‘,’ </Provider>, //add document.getElementById(" ") ); In the above file, we can see that the location of the ‘App’ component is moved from the root folder to ‘ ’ folder. Then we imported two Redux components ‘ ’ and ‘ ’. initializes the . The <Provider /> makes the Redux store available to any nested components that have been wrapped in the connect() function. The ‘ ’ is going to be defined in a separate file which is being imported here. components createStore Provider CreateStore Store reducer actions/index.js addBook = ({ : , : .now(), title }); removeBook = ({ : , id }); export const => title type "ADD_BOOK" id Date export const => id type "REMOVE_BOOK" The index.js file under folder defines the various actions that are required in the app. Each action is defined by providing some attributes like ‘ ’ and the inputs needed to perform that action. For our app, we have defined two action objects ‘ADD_BOOK’ and ‘REMOVE_BOOK’ giving other information like ‘id’ and ‘title’. actions type of the action These action objects would be used by the reducer methods defined in the files under the ‘ ’ folder. reducer reducers/books.js books = { (action.type) { : [ ...state, { : action.id, : action.title } ]; : state.filter( book.id !== action.id); : state; } }; books; const ( ) => state = [], action switch case "ADD_BOOK" return id title case "REMOVE_BOOK" return => book default return export default The file ‘ ’ defines the methods ‘ADD_BOOK’ and ‘REMOVE_BOOK’ which add and remove books from the store. We can have more than one file defining the reducers for various actions required in the app, but then we need to use another reducer ‘ ’ which combines them into one. For demo purposes, I have also defined ‘ ’ which combines other reducers though we have only one other reducer, i.e. books.js. books.js index.js index.js reducers/index.js { combineReducers } ; books ; combineReducers({ books }); import from "redux" import from "./books" export default The file ‘ ’ under the ‘ ’ folder combines other reducers defined in other files, into one, and makes it available to the store. index.js reducers So far, we have added the above three files and are going to modify other files as discussed below. components/App.js React ; BookForm ; BookList ; { render() { ( <h1> React to Redux</h1> <BookForm onSubmit={this.addBook} /> <BookList books={this.state.books} removeBook={this.removeBook} /> </div> ); } } export default App; import from "react" // import BookForm from "./components/BookForm"; // import BookList from "./components/BookList"; import from "../containers/BookForm" //add import from "../containers/BookList" //add . class App extends React Component // state = { // books: [] // }; // addBook = book => { // this.setState(state => ({ // books: [book, ...state.books] // })); // }; // removeBook = id => { // this.setState({ // books: this.state.books.filter(book => book.id !== id) // }); // }; return < > div In the file above we changed the top two lines just because we have changed the locations of those files. Then we have removed ‘declaring the state’, and methods for ‘ ’ and ‘ ’ the books. Because in Redux, is maintained by Store and add and delete methods are handled by the reducers defined in ‘ ’ file. App.js adding deleting state reducers/books.js components/Book.js React ; Book = { { book, removeBook } = props; handleRemoveBook = removeBook(book.id); ( <div> // {book.title} <button onClick={props.onDelete}>Delete</button> {book.title} <button onClick={handleRemoveBook}>Delete</button>//add </div> ); }; Book; import from "react" const => props // const { book } = props; const //add const => () //add return < > div </ > div export default In the above file ‘ there is not much change except for the syntax Book.js’ containers/BookForm.js React ; { connect } ; { addBook } ; { () { (); .state = { : }; .handleChange = .handleChange.bind( ); .handleSubmit = .handleSubmit.bind( ); } handleChange(event) { { name, value } = event.target; .setState({ [name]: value }); } handleSubmit(event) { event.preventDefault(); { title } = .state; { addBook } = .props; (title) { addBook(title); .setState({ : }); } } render() { ( <input type="text" value={this.state.title} name="title" placeholder="Book Title" onChange={this.handleChange} /> <input type="submit" value="Submit" /> </form> ); } } // export default BookForm export default connect(null, { addBook })(BookForm); /add import from "react" import from "react-redux" //add import from "../actions" //add . class BookForm extends React Component constructor super this title "" this this this this this this const this // this.props.onSubmit({ // id: Date.now(), // title: this.state.title // }); const this //add const this //add if //add //add this title "" return < = > form onSubmit {this.handleSubmit} In this file, we are importing ‘ ’ from ‘ ’ and ‘ ’ from . Accordingly, we are deleting the method and in its place using the ‘ ’ method which is defined in file. We are passing the ‘ ’ which was initially stored in the ‘ ’ of the component, to ‘ ’ and passing this ‘ ’ as ' ' method which was used by the ‘ ’ function that is connecting the and components. connect react-redux addBook actions/index.js OnSubmit addBook actions/books.js title state addBook addBook mapDispatchToState connect Store BookForm containers/BookList.js React ; Book ; { connect } ; { removeBook } ; { { books } = state; { books }; } mapDispatchToProps = ({ removeBook: dispatch(removeBook(id)) }); BookList = { ( <div> {books.map( ( <ul key={book.id}> <Book book={book} removeBook={removeBook} /> < div> ); }; connect(mapStateToProps, mapDispatchToProps)(BookList); import from "react" // import Book from "./Book"; import from "../components/Book" //add import from "react-redux" //add import from "../actions" //add ( ) function mapStateToProps state //add const //add return //add //add const => dispatch //add => id //add //add // const BookList = props => { // return ( // <div> // {props.books.map(book => ( // <ul key={book.id.toString()}> // <Book book={book} onDelete={() => props.removeBook(book.id)} /> // </ul> // ))} // </div> // ); // }; const ( ) => { books, removeBook } //add return //add //add => book //add //add //add /ul> / /add ))} / /add </ //add //add //add // export default BookList; export default //add //add Finally, we have replaced almost all the code in . On the top of the file we are importing ‘ ’ and ‘ ’. In this component we are both receiving data from as a book list to display on the screen and sending data to by way of ‘ ’ if the ‘ ’ button is clicked for a book. BookList.js connect removeBook Store Store removeBook remove Thus, we have defined both the methods ‘ ’ and ‘ ’ on top of the file and used ‘ ’ at the bottom of the file passing both these methods and connecting and components. mapStateToProps mapDispatchToProps connect Store BookList Once your files are ready, run ‘npm start’ and you can see the working of your app exactly like before when you did not use Redux. Conclusion Redux is more powerful and is very useful in large applications. Here, we tried just to understand how Redux functions. This knowledge should be useful when you start developing larger applications. I am not a pro but a learner like you and I thought I should share the understanding I gained with the readers so that it would save some time for you. I welcome suggestions from anyone to improve the content. Happy coding :) React app : https://github.com/IBTechRaj/redux-article-react Redux app : https://github.com/IBTechRaj/redux-article-redux