Creating an app with react and firebase - part one
Tags: react, firebase
Published: 2017-12-24 22:14:31

---
title: Creating an app with react and firebase - part one
published: true
description: Part one goes through creating a fully functional react app
tags: react, firebase
---

After having explored the basics of firebase and react, I thought I'd use them all together in this tutorial. In this three part series, I am going to create another todo app. I'm going to use react, the basics of which I covered [here](https://dev.to/aurelkurtula/introduction-to-react-532) where I made a simpler version of the same app. I'm also going to use react routing, which I also covered [in this post](https://dev.to/aurelkurtula/introduction-to-react-router-ha).

Since I don't want this tutorial to be very long, I'm going to add firebase to this project in part two. In that tutorial, we'll move the data from our react component state to the firebase database. Then in part three we'll add authentication where users can add their own private todo items.

### Create the static markup

First we'll quickly create the basic design of the app. Everything I'll do here I have already covered else where. Let's start by installing the package we need for routing in react. 

    yarn add react-router-dom

The `App` component is going to be the main component. It will hold the state and the logic of the application. However, let's start by creating the basic structure. If you want to start in [codesandbox](https://codesandbox.io/) that means start editing in `index.js`. If you create a react application through the terminal, you start in `src/App`. 


    import React, {Component} from 'react' 
    import { BrowserRouter, Route, Link } from 'react-router-dom';
    import './App.css'
    class App extends Component {
      state = {
        items: {
          1123: {
            item: 'item one',
            completed: false
          },
          2564321: {
            item: 'item two',
            completed: true
          }
        }
      }
      render() {
        return (
          <BrowserRouter>  
            <div className="wrap">
              <h2>A simple todo app</h2>
              <ul className="menu">
                <li><Link to={'/'}>To do</Link></li>
                <li><Link to={'/completed'}>Completed</Link></li>
              </ul>
              <Route exact path="/" render={props => {
                  let lis = []
                    for(let i in this.state.items){
                      if(this.state.items[i].completed === false){
                        lis.push(<li key={i}>{this.state.items[i].item} <span >x</span></li>)
                      }
                    }
                    return(<ul className="items"> { lis } </ul>  )
                  }   
                }  />
              <Route exact path="/completed" render={props => {
                  let lis = []
                    for(let i in this.state.items){
                      if(this.state.items[i].completed === true){
                        lis.push(<li key={i}>{this.state.items[i].item} <span >x</span></li>)
                      }
                    }
                    return(<ul className="items"> { lis } </ul>  )
                  }   
                }  />
            </div>
          </BrowserRouter>   
        );
      }
    }
    export default App;

When loading the app in your browser, you'll be able to navigate between the homepage and `/completed` and see the difference.

For an explenation on how the above code works, read my previous tutorial on the basics of [React Router](https://dev.to/aurelkurtula/introduction-to-react-router-ha)

### Using child components 

Let's create a child component which will take care of the duplicate code. Create a file at `components/ItemsComponent.js` and add the following code.

    import React from 'react'
    const ItemsComponent=({items, done})=> {
        let lis = []
        let mark = done === false ? '\u2713' : 'x';
        for(let i in items){
            if(items[i].completed === done){
              lis.push(<li key={i}>{items[i].item} <span >{mark}</span></li>)
            }
        }
        return(<ul className="items"> {lis} </ul>  )
    }
    export default ItemsComponent;

That is a stateless functional component, as you can see, it doesn't need a class (a shout out to @omensah for nudging me on this direction). It's perfect for cases like these, where the logic doesn't require to make use of functionality that we'd otherwise inherit from `Component` class. Cory House has perfectly compared the two styles [in this post](https://hackernoon.com/react-stateless-functional-components-nine-wins-you-might-have-overlooked-997b0d933dbc) 

Let's modify the `App` component to make use of `ItemsComponent` which will also clarify the deconstructed arguments in line 2. 

    import ItemsComponent from './components/ItemsComponent';
    class App extends Component {
      ..
        return (
          <BrowserRouter>  
            <div className="wrap">
              ...
              <Route exact path="/"
                render={props => 
                  <ItemsComponent  items={this.state.items} done={false}/> 
                }/>
              <Route exact path="/completed" 
                render={props => 
                  <ItemsComponent  items={this.state.items} done={true}/> 
                }/>
            </div>
          </BrowserRouter>   
        );
      }
    }
    export default App;

We render the `ItemsComponent` component using `render` rather than using the `component` attribute, which I [covered when writing about react routers](https://dev.to/aurelkurtula/introduction-to-react-router-ha) because we needed to pass it the items a boolian to signal which items to display. With that the use of ES6 deconstruction is self explanatory:

    const ItemsComponent=({items, done})=> { ... }        

The above could have otherwise be writen as 

    const ItemsComponent=(props)=> { ... }

Which we would have had to then reach in the `props` object to retrieve `items` or `done`.

### Adding actions 

The first two actions that we'll work on are the ability to mark an item as complete, and also completely delete any completed item. 

As I said the `App` component is going to be the main component. It holds our main state. So let's write the methods that modifies the state. 

    class App extends Component {
      state = {
        items: {
          1123: {
            item: 'item one',
            completed: false
          },
          2564321: {
            item: 'item two',
            completed: true
          }
        }
      }
      completeItem=(id)=>{
        let items =   {
            ...this.state.items, 
            [id]: {...this.state.items[id], completed: true      }
          }
        this.setState({ items })
      }
      deleteItem = (id) => {
        let  {[id]: deleted, ...items} = this.state.items;
        this.setState({ items })
      }
      ...

`completeItem` method takes the items from the current state, then we select the item with the relevant `id`, and finally change its `completed` property to `true`.

Deleting the relevant object is slightly different. I'm currently trying to learn more about the spread operator and that's why I added it above. I found the snippet ... guess where? ... [at stackoverflow](https://stackoverflow.com/questions/36553129/what-is-the-shortest-way-to-modify-immutable-objects-using-spread-and-destructur)

Next, `completeItem` and `deleteItem` methods need to be passed to the `ItemsComponent`

      render() {
        return (
          ...
              <Route exact path="/"
                render={props => 
                  <ItemsComponent  
                    items={this.state.items} 
                    done={false}
                    action={this.completeItem}
                    /> 
                }/>
              <Route exact path="/completed" 
                render={props => 
                  <ItemsComponent  
                    items={this.state.items} 
                    done={true}
                    action={this.deleteItem}
                    /> 
                }/>
           ...
        ) 

Finally we just strap `action` to an `onClick` event over at `components/itemsComponent.js`

    const ItemsComponent=({items, done, action})=> {
        let lis = []
        let mark = done === false ? '\u2713' : 'x';
        for(let i in items){
            if(items[i].completed === done){
              lis.push(<li key={i}>{items[i].item} 
                <span onClick={()=> action(i)}>{mark}</span></li>)
            }
          }
          return(<ul className="items"> {lis} </ul>  )
    }


Note, the only thing that's changed is the deconstruction of the `action` method in the first line. Then I added it to the span. `i` is the id of each object within the `items` object.

### Adding items 

A todo Application is no good if users can't add items. At the moment, the item's are hard coded, but that was to help us get to this point. 

The way this will work is that I want users to be able to add new items only when thay are viewing the uncompleted items, in other words, only when they are at the root path and not the `/completed` path. Let's add the input box inside the `components/ItemsComponent.js` file:

    const ItemsComponent=({items, done, action})=> {
        ...
        return (
            <div>
                {done
                ? (<ul className="items"> {lis} </ul>)
                : (
                <div>
                    <form>
                        <input type="text" /> 
                    </form>
                    <ul className="items"> {lis} </ul>
                </div>
                )}
            </div>
        );                   
    }

Remember, `done` is a boolian, if `true` it means the items are marked as completed, hence we do not want to see the form, else, we do.

React requires the outer div to wrap the entire output, and it also requires the `form` and `ul` to be wrapped with an element. 

Finally, just as with the delete and complete operations, we'll add the form's logic at `App` components and link it via props with the form. Let's create the logic in `App.js`

    class App extends Component {
      ...
      addItem=(e)=> {
        e.preventDefault();
        let items =  {
          ...this.state.items, 
          [new Date().valueOf()]: {
            item: this.todoItem.value, 
            completed: false     
          }
        }
        this.setState({
          items
        });
      }
      render() {
        return ( 
            ...
              <Route exact path="/"
                render={props => 
                  <ItemsComponent  
                    ...
                    addItem={this.addItem}
                    inputRef={el => this.todoItem = el}
                    /> 
                }/>
             ...   
        );
      }
    }

`addItem` will execute on form submit. Then it simply adds an item to the state. `new Date().valueOf()` is a basic way of creating a unique id. `this.todoItem.value` is created from the `inputRef` attribute that we created in `ItemsComponent`. You can read more about Refs (as they are called) in the [documentation](https://reactjs.org/docs/refs-and-the-dom.html)

Now let's use `addItem` and `inputRef` in the form over at `ItemsComponent.js`.

    const ItemsComponent=({items, done, action, addItem, inputRef})=> {
        ...
        return (
          ...
           <form  onSubmit={addItem}>
              <input ref={inputRef} type="text" /> 
           </form>
           <ul className="items"> {lis} </ul>
           ...
        );                   
    }

We attach the `input` node as a reference to `inputRef` (which is passed through props).

## Conclusion

So far we have a basic react application where we can add items, mark them as complete then delete any that are completed. We also made use of routing to differentiate between the two.

The completed project can be found at [github](https://github.com/aurelkurtula/todo-app-with-react-and-firebase). I'll have a branch for each tutorial.

The [next tutorial](https://dev.to/aurelkurtula/creating-an-app-with-react-and-firebase---part-two-5hmc) is going to connect the react state with the Firebase database.