Skip to content

Creating our Todo List

First, lets create the centered box inside our App.tsx that will be container for our list.

import { Provider } from "react-redux";
import store from "./store";

function App() {
    return (
        <Provider store={store}>
            <div className="flex justify-center items-center h-screen">
                <div className="shadow-lg rounded-lg w-[500px]"></div>
            </div>
        </Provider>
    );
}

export default App;

Now, we want to display our list and all necessary things inside this container.

The main idea is to divide list in two components for now:

  1. ListHeader - used to handle new data input and button

  2. List - used to display our current list items

First we will create components folder inside ./src where we will store all our components files.

Lets first create ListHeader.tsx inside components folder that will contain our input and "Add" button. We will also add some Tailwind CSS classes to make it look better.

function ListHeader() {
    return (
        <div className="flex items-center p-8">
            <form className="basis-full group relative">
                <input
                    className="focus:ring-2 focus:ring-blue-500
                        focus:outline-none w-full text-sm leading-6
                        text-gray-900 placeholder-gray-400
                        rounded-md py-2 px-4 ring-1 ring-gray-200 shadow-sm"
                    type="text"
                    aria-label="Add to list"
                    placeholder="Add to list"
                />
            </form>
            <button
                type="button"
                className="animate-bounce whitespace-nowrap bg-indigo-600
                    text-white text-sm leading-6 font-medium py-2 px-4 ml-2
                    rounded-lg transition ease-in-out delay-0 bg-blue-500
                    hover:-translate-y-1 hover:bg-indigo-500 duration-300"
            >
                + Add
            </button>
        </div>
    );
}

export default ListHeader;

Now, lets create our List.tsx component that will display the todo list below our ListHeader component.

function List() {
    return (
        <ul>
            <li>Todo 1</li>
            <li>Todo 2</li>
            <li>Todo 3</li>
        </ul>
    );
}

export default List;

You will note that our list for now consist of predefined values, but we will come back to that later.

Now, the good practice is to make a container, for example TodoList that will handle everything related to our Todo list. We can do that by creating a new containers folder in ./src and adding a new tsx file called TodoList.tsx.

Info

Component which is responsible for fetching data and displaying is called smart or container components. Data can come from redux, any network call or third party subscription.

Dumb/presentational components are those which are responsible for presenting view based on props received.

import ListHeader from "../components/ListHeader";
import List from "../components/List";

function TodoList() {
    return (
        <div className="flex justify-center items-center h-screen">
            <div className="shadow-lg rounded-lg w-[500px]">
                <ListHeader />
                <List />
            </div>
        </div>
    );
}

export default TodoList;

The last step is to import our container into App.tsx.

import { Provider } from "react-redux";
import TodoList from "./containers/TodoList";
import store from "./store";

function App() {
    return (
        <Provider store={store}>
            <TodoList />
        </Provider>
    );
}

export default App;

Now our application should look something like this:

Todo list without list styles
Todo list without list styles

You should see the list of predefined todos displayed below your input and button.

But it looks ugly. Right?

Lets add some Tailwind classes to our List component to make it look better.

function List() {
    return (
        <ul className="p-8 pt-0 divide-y">
            <li className="p-2">Todo 1</li>
            <li className="p-2">Todo 2</li>
            <li className="p-2">Todo 3</li>
        </ul>
    );
}

export default List;

Also, while we are here, lets add a checkbox to every item so it can be marked as done, and delete button, so we can delete specific todo from the list.

function List() {
    return (
        <ul className="p-8 pt-0 divide-y">
            <li className="flex items-center p-2">
                <input type="checkbox" className="h-4 w-4 mr-2 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded" />
                <p className="w-full">Todo 1</p>
                <button type="button" className="w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-2 py-0.5 bg-white text-base font-medium   text-gray-700 hover:bg-gray-100 focus:outline-none focus:ring-1 focus:ring-offset-2 focus:ring-red-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
                    Remove
                </button>
            </li>
            <li className="flex items-center p-2">
                <input type="checkbox" className="h-4 w-4 mr-2 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded" />
                <p className="w-full">Todo 2</p>
                <button type="button" className="w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-2 py-0.5 bg-white text-base font-medium text-gray-700 hover:bg-gray-100 focus:outline-none focus:ring-1 focus:ring-offset-2 focus:ring-red-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
                    Remove
                </button>
            </li>
            <li className="flex items-center p-2">
                <input type="checkbox" className="h-4 w-4 mr-2 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded" />
                <p className="w-full">Todo 3</p>
                <button type="button" className="w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-2 py-0.5 bg-white text-base font-medium text-gray-700 hover:bg-gray-100 focus:outline-none focus:ring-1 focus:ring-offset-2 focus:ring-red-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
                    Remove
                </button>
            </li>
        </ul>
    );
}

export default List;

Now, you should see something like this

Todo list with list styles applied
Todo list with list styles applied

Now we are ready to add some functionality to it!


Last update: March 28, 2022