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:
-
ListHeader - used to handle new data input and button
-
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:
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
Now we are ready to add some functionality to it!