How To Build A ToDo App using React with Firebase and Redux

Author profile picture

@arslanArslan

Full Stack developer /Lead Developer/Project Manager/Software Engineer

In order to be deemed as a capable developer, you need to be able to utilize the data of any app that you are building. This means that you need to know how to write some data into your app, display it wherever needed, add features that will allow the user to change that data in future, and delete it if required.
These four things are collectively known as CRUD (Create, Read, Update, and Delete). A ToDo App is based on this concept.
You will find many resources on the internet that will show you how to build different types of to-do apps in different technologies.
In this article, I will show you how to build a ToDo app in one of JavaScript’s most popular framework— React!
Along with using React, we will also use the Redux library to manage the state of this app. Though Redux is not necessary for an app as simple as a ToDo app, it will help you understand the steps needed in order to add Redux to any other React App!
Google’s Firebase is another amazing tech that we will be using in this application. Firebase can provide us with many different features and services such as Authentication, Storage, Testing, and Database. In this post, however, we will only be using Firebase to store the app’s data inside the Firebase’s Real-time Database.

Getting Started

Before you starting building this app, make sure that your system is well prepared for the journey ahead. This includes checking that your system has the latest versions of Node, NPM, and the Create-React-App CLI installed.
If you don’t have these, or if you are not sure if you are on the latest version, then:
  • Uninstall the Node.js software from your system, and go to nodejs.org and install the latest version.
  • Update NPM by running the following command in the terminal:
  • $ npm install -g npm
    • The Create-React-App CLI is now on version 2.1.3. You can update it by installing it using npm, or you can simply use the npx command that will use the CLI without installing it on your system.
    • Also make sure that you have a good Code Editor. I personally like to use VS Code.
    Next, create a new React App Project Directory using the 
    create-react-app
     CLI as shown below:
    $ create-react-app firedux-todo
    
    $ cd firedux-todo
    You will then get a new folder on your system named 
    firedux-todo
     that will contain some basic code to get you started working on the app. You can run the 
    start
     script using 
    npm 
    or
     yarn
     to launch the app on the browser at 
    localhost:3000
    Next, go to the 
    src
     folder and delete everything from inside it, except the 
    registerServiceWorker.js
     file. Nothing bad will happen if you delete it, but I have big plans for it later on 😈.
    Once you are done purging all the files from the 
    src
     folder, we will work on integrating Redux into our App!

    Adding Redux

    If you are not familiar with this term, then Redux is a state management library built for maintaining the data of JavaScript applications.
    The main thing to know about Redux is that it will keep all the data of our application in a single place named Store. When any component of our app requires some data, Redux will simply take it from the store and give it to the component.
    To begin, we need to install the 
    redux
     library into our app. Along with this, we will install the 
    react-redux
     library to help connect React with Redux, and the 
    redux-thunk
     library to act as a middleware and handle asynchronous actions in Redux. This is important since we are using Firebase as the database, so chances are that we will need to perform some asynchronous request to fetch the data from there.
    yarn add redux react-redux redux-thunk
    
    Once installed, we can start working on Redux side of our app by creating the Reducers. Reducers are what Redux uses to actually change the state of our app.
    Insider the 
    src
     folder, create a new folder named 
    reducers
     with a file named 
    data.js
     inside it.
    The reducer is actually a function that has two arguments — the initial state and action. An action is triggered by an app component, which is then goes through all the reducers. The reducers check what kind of action was triggered by the component and it suits the reducer, data gets changed.
    Inside the 
    data.js
     file, write the following function:
    import {FETCH_TODOS} from '../actions/types';export default (state = {}, action) => {
      switch(action.type) {
        case FETCH_TODOS:
          return action.payload;
        default:
          return state;
      }
    };
    The reducer function above checks if the action triggered by the component is of type 
    FETCH_TODOS
    . If it is, then it will update the state of our app with the list of
    todos
    that will be fetched by the action.
    Rather than importing multiple reducer functions, we can simply combine them into one reducer by creating a new file named 
    index.js
     in the same folder and writing the following code:
    import {combineReducers} from 'redux';
    import data from './data';export default combineReducers({
      data
    });
    The 
    redux
     library contains a function named 
    combineReducers 
    that can take multiple reducers and combine them into one reducer.
    Next, we will create the Redux store where all the app data will be kept. Inside the 
    src
     folder, create a file named 
    index.js
    .
    The state of any React app is said to flow in only one direction, from the top most file to bottom. The 
    index.js
     file is the top most file of our app because this is where the 
    App
     component will be rendered. The 
    App
     component can further have other components inside it. So we need to create the store in the 
    index.js
     file as shown below:
    import React from 'react';
    import ReactDOM from 'react-dom';
    import {Provider} from 'react-redux';
    import {createStore, applyMiddleware} from 'redux';
    import reduxThunk from 'redux-thunk';
    import reducers from './reducers';
    import App from './App';
    import * as serviceWorker from './serviceWorker';const store = createStore(reducers, {}, applyMiddleware(reduxThunk));ReactDOM.render(
      <Provider store={store}>
        <App />
      </Provider>,
      document.getElementById("root")
    );
    serviceWorker.register();
    Apart from creating our store with reducers and 
    reduxThunk
     as the
    middleware
    , we are also rendering the App component using the  
    ReactDOM
    . The App component is wrapped in the Provider component of 
    react-redux
     library. The 
    Provider
     also takes the 
    store
     prop and declares it as the entire application’s store.
    At first,
    Redux
    may seem to confuse you, but it works in a very well defined manner. First, a user needs to interact with a React component. This component will call an action creator, which as its name suggests will produce action. This action is given to the reducers, which will then update the application state.

    Setting Up Firebase

    To start, go to the homepage of Firebase and click on the Create New Project or the App Project Button. Also, make sure that you have logged into your google account.
    You will then be required give a name to your project. You can give it the same as your React App, as it will help you keep things simple. But it is not mandatory to have the same name at both places. Once Firebase is done configuring the project, you will be directed to a page similar to this:
    Let’s start configuring the Firebase Realtime Database for our React App. Click on the Database tab (you can also find it on the left hand side of the screen) Make sure that you are selecting the “Realtime Database” and not the “Cloud Firestore Database”, and then click on the 
    Create database
     button shown below:
    Select the “Start in test mode” option and click on the enable button.
    With this, we have to set up the Firebase project and created a Realtime Database for our app. But we still need to connect the Firebase project with our React Project.
    To do so, we need to install the Firebase library inside our React app using
     npm
     or 
    yarn
     as shown below:
    $ npm install --save firebase
    // or
    $ yarn add firebase
    In the Firebase project’s homepage, you will notice three circular icons. The first two will contain code that will help you connect the firebase project to an iOS and Android app respectively, while the third one will have code that will help you connect the project to a web app (which is what we want). Click on it and copy the  
    apiKey,
     
    authDomain,
     
    databaseURL,  projectId
    storageBucket,
    and 
    messagingSenderId
     values. These values are unique for each user’s each project and hence I am sharing the screenshot for this part.
    Inside the React project directory, go to the 
    src
     folder and create a new file named 
    firebase.js
    . Inside this folder, write the values that we copied from the Firebase here as shown below:
    import * as firebase from 'firebase';const config = {
      apiKey: "ENTER YOURS HERE",
      authDomain: "ENTER YOURS HERE",
      databaseURL: "ENTER YOURS HERE",
      projectId: "ENTER YOURS HERE",
      storageBucket: "ENTER YOURS HERE",
      messagingSenderId: "ENTER YOURS HERE"
    }
    firebase.initializeApp(config);
    const databaseRef = firebase.database().ref();
    export const todosRef = databaseRef.child("todos")
    
    In contrast to Redux, the Firebase database has something called the Firebase Ref. This is a reference to the data that we want to access from the Firebase database.
    The Firebase Ref emits a series of value events, which are Firebase’s way of telling us that it has received some new data from the application.
    Ok! So we have connected our React app with the Firebase Project! We are going to use the Firebase’s Realtime database to store the list of 
    todos
    . We will add a listener to the list of 
    todos
     so that whenever the list changes, the app will know about the change and fetch the new data from Firebase and display it.
    To do this, we have one last thing to take care of on the Redux side of things, and that is called Actions!

    Setting Up Actions

    Even though our React and Firebase are connected, we still need Firebase to work with Redux, because Redux is handling the local data of our App.
    For that we are going to take the Firebase Ref that we have named as 
    todosRef
     and stick it into an action creator. So whenever the Firebase Ref emits a value event, the Firebase Ref will be turned into an action and sent to the reducers.
    Inside the 
    src
     folder, create a new folder called 
    actions
    . Inside this folder create a new file named 
    index.js
    . This file will contain 3 actions — one to add a todo to the list, another to remove it from the list, and the third one to listen for any changes in the list and according fetch the changes to the app.
    import {todosRef} from '../firebase'
    const FETCH_TODOS = 'FETCH_TODOS';export const addToDo = newToDo => async dispatch => {
      todosRef.push().set(newToDo);
    };export const completeToDo = completeToDo => async dispatch => {
      todosRef.child(completeToDo).remove();
    };export const fetchToDos = () => async dispatch => {
      todosRef.on("value", snapshot => {
        dispatch({
          type: FETCH_TODOS,
          payload: snapshot.val()
        });
      });
    };

    Final Stretch

    We are almost done with this app. All that is left to do is build the UI side of things. For that, we will create a new folder named 
    components
     inside the 
    src
     folder.
    Inside the 
    components
     folder, create a file named 
    ListItem.js
    . This file will render each individual ToDo item. Each item will contain a button which when clicked will deem the ToDo as completed and remove it from the list. This is achieved with the help of the 
    completeToDo
     action that we had created in the actions section of this post. The actions are connected to the component with the help of the connect method of 
    react-redux
     library.
    import React, {Component} from 'react';
    import {connect} from 'react-redux';
    import {completeTodo} from '../actions';class ListItem extends Component {
      handleComplete = completeTodo => {
        const {completeTodo} = this.props;
        completeTodo(completeTodo);
      };
      render() {
        const{todoId, todo} = this.props;
        return (
          <div key="toDoName">
            <h4>
              {todo.title}
              <span onClick={() => this.handleComplete(todoId
                <i>Done</i>
              </span>
            </h4>
          </div>
        );
      }
    }export default connect(null, {completeTodo})(ListItem);
    Next, we need to create another file named 
    List.js
    . This file will contain a form that we will use to create a new
    Todo
    . It will appear on the screen when we click on the Add button. This component will trigger the 
    addTodo
     action when submitting form. And it will listen for changes in database using 
    fetchTodos
     action. The connect method in this component will take in the 
    mapStateToProp
     function, which we will use to access the data from the store.
    Finally, We need to render these components into the 
    src
    folder’s  
    App.js
    file as shown below:
    import React, {Component} from 'react';
    import List from './components/List';class App extends Component {
      render() {
        return (
          <div>
            <List/>
          </div>
        );
      }
    }
    export default App;
    And our app is complete! After adding some styling, it will look like this:
    If you take a look at the Firebase database, you will see that something has changed over there:

    Conclusion

    In this post, we saw how to create a Redux store with Reducers and attached it to our React App. We also created actions and saw how to trigger them from our React Applications.
    Thanks for reading this post. I hope it helped you understand how to use React with Redux and Firebase!
    If you need help in any kind of development project & I can also provide you consultancy about your project. I am top rated freelancer. You can hire me directly on Upwork. You can also hire me on Freelancer.
    If you have any comment, question, or recommendation, feel free to post them in the comment section below!





















    Tags

    The Noonification banner

    Subscribe to get your daily round-up of top tech stories!