Let's create a TODO app on react!

Creating a TODO app on react is really simple. In fact you can do it in just a few lines! Today, we will be creating a very basic TODO app. Let's get started.

First, we must define our function and export it.
function TodoApp() {
 // TODO: implement me.
}

export default TodoApp;
Next, we will define our states. First we will have a list of TODOs, and another TODO that determines our input.
function TodoApp() {
	const [todos, setTodos] = useState([]);
    const [todo, setTodo] = useState({date: new Date(), value:''});
}

export default TodoApp;
Next, we will create a form with a text box and a button that adds the TODO value into our list of TODOs.
import { useState } from "react";

function TodoApp() {

    const [todos, setTodos] = useState([]);
    const [todo, setTodo] = useState({date: new Date(), value:''});

    return <div className="todo-box">
        <form onSubmit={addTodo}>
            <input type="text" value={todo.value} className="todo-input-box"
            aria-label="todo-input-box" onChange={updateTodo}/>
            <button type="submit" className="todo-button">Add</button>
        </form>
    </div>;

}

export default TodoApp;
This is what our react app will look like. It's really basic and right now we don't have any CSS invovled.
Next we will implement addTodo and updateTodo.
import { useState } from "react";

function TodoApp() {

    const [todos, setTodos] = useState([]);
    const [todo, setTodo] = useState({date: new Date(), value:''});

    const addTodo = (event) => {
        if(todo.value.length < 1) {
            event.preventDefault();
            return;
        } 
        
        setTodos(current => [...current, todo]);
        setTodo({date: '', value: ''});
        event.preventDefault();
    };

    const updateTodo = (event) => {
        setTodo({date: new Date(), value: event.target.value});
    }

    return <div className="todo-box">
        <form onSubmit={addTodo}>
            <input type="text" value={todo.value} className="todo-input-box"
            aria-label="todo-input-box" onChange={updateTodo}/>
            <button type="submit" className="todo-button">Add</button>
        </form>
    </div>;

}

export default TodoApp;
addTodo will add a TODO value into our list of TODOs. updateTodo simply sets the value of our todo. Next, we will publish the list of todos.
import { useState } from "react";

function TodoApp() {

    const [todos, setTodos] = useState([]);
    const [todo, setTodo] = useState({date: new Date(), value:''});

    const addTodo = (event) => {
        if(todo.value.length < 1) {
            event.preventDefault();
            return;
        } 
        
        setTodos(current => [...current, todo]);
        setTodo({date: '', value: ''});
        event.preventDefault();
    };

    const updateTodo = (event) => {
        setTodo({date: new Date(), value: event.target.value});
    }

    return <div className="todo-box">
        <form onSubmit={addTodo}>
            <input type="text" value={todo.value} className="todo-input-box"
            aria-label="todo-input-box" onChange={updateTodo}/>
            <button type="submit" className="todo-button">Add</button>
        </form>

        <ul className="todos-box">
            {todos.map((c, index) => {
                return <li key={index}>
                    <div className="todo-text">{c.value}</div>
                    <div className="todo-date">{c.date.toString()}</div>
                </li>
            })}
        </ul>
    </div>;

}

export default TodoApp;
Now our TODO app is almost done.
It's time we polish it with some CSS. This is what our CSS will look like.
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@100;200&display=swap');

.todo-box {
    border: solid 1px rgb(209, 208, 208);
    width: 70%;
    margin: 100px auto;
    padding: 20px;
    background-color: rgb(236, 235, 235);
    font-family: 'Montserrat', sans-serif;
}

.todo-box > form {
    display: grid;
    grid-template-columns: auto auto;
    grid-gap: 10px;
}

.todo-input-box {
    border: solid 1px rgb(3, 133, 165);
    font-size: 24px;
    border-radius: 5px;
    font-family: 'Montserrat', sans-serif;
}

.todo-input-box:focus {
    outline: none;
}

.todo-button {
    background-color: rgb(3, 133, 165);
    color: #FFFFFF;
    font-size: 24px;
    border-radius: 5px;
    border: none;
    padding: 3px;
    font-family: 'Montserrat', sans-serif;
}

.todos-box {
    padding: 0;
}

.todos-box > li {
    list-style-type: none;
    border: solid rgb(209, 208, 208) 1px;
    padding: 10px;
    margin: 10px 0;
    border-radius: 5px;
    background-color: rgb(248, 246, 246);
}

.todo-text {
    margin-bottom: 5px;
}

.todo-date {
    font-size: 13px;
}
Next, let's import our CSS so we can make our TODO app pretty.
import "./todo.css";
Here is the final output of our code.
import { useState } from "react";
import "./todo.css";

function TodoApp() {

    const [todos, setTodos] = useState([]);
    const [todo, setTodo] = useState({date: new Date(), value:''});

    const addTodo = (event) => {
        if(todo.value.length < 1) {
            event.preventDefault();
            return;
        } 
        
        setTodos(current => [...current, todo]);
        setTodo({date: '', value: ''});
        event.preventDefault();
    };

    const updateTodo = (event) => {
        setTodo({date: new Date(), value: event.target.value});
    }

    return <div className="todo-box">
        <form onSubmit={addTodo}>
            <input type="text" value={todo.value} className="todo-input-box"
            aria-label="todo-input-box" onChange={updateTodo}/>
            <button type="submit" className="todo-button">Add</button>
        </form>

        <ul className="todos-box">
            {todos.map((c, index) => {
                return <li key={index}>
                    <div className="todo-text">{c.value}</div>
                    <div className="todo-date">{c.date.toString()}</div>
                </li>
            })}
        </ul>
    </div>;

}

export default TodoApp;
And this is what our output should look like.

Comments