Featured Post

BUILD A TODO LIST IN PYTHON

Image
Build a TODO List in Python Overview The objective is to build a todo list to which we can add items, remove the added items, edit the items and even if required, delete out the entire list itself. We will learn here step by step, how to build the todo list with the above  CRUD (Create, Remove, Update/edit, and Delete ) features.  This is a CRUD list  app  that we are building as we can Create, Remove, Update items in the list and Delete the entire list itself. We will be using Python3 to build this Project. Importing os and time We import time to let the screen pause for a while before clearing  and we import os to clear the screen . Initializing the list We initialize the todo list with an empty list as there are not items added yet to the list and this is represented in the code aby using an empty square braces   toDoList = [] Defining the print list  The def keyword is used to define a function in python. In the below code, we define the funct...

Build Todo App React Hooks

 Build Todo App React Hooks



This tutorial will teach you how to build a To do list App using React, hooks, in a step-by-step manner with complete code and explanations of React hooks concepts in a very easy-to-understand manner.
Below, I am displaying the code editor with the first part of the code for creating a Todo function for the javascript code:



START THE APP

import React, {useStatefrom 'react';
import ReactDOM from 'react-dom';

To start the App, you need to import React useState() from 'react' and

also import ReactDOM from 'react-dom'

By importing the useState() , we are able to use the state hook without the need to use classes in React apps.

By importing the default ReactDOM, we are able to write JSX and carry out DOM related methods.


But before that, as usual, for the html code, it is :

HTML
<div id = "container">


 
JAVASCRIPT 
import React, {useStatefrom 'react';
import ReactDOM from 'react-dom';

function Todo({todo,index,completeTodo,removeTodo}){
  return(
    <div className = 'todo' style = {{ textDecoration: todo.isCompleted ? 'line-through ' : ''}}>
     {todo.text}
       <div>
         <button onClick = {() => completeTodo(index)}>COMPLETE</button>
         <button onClick = {() => removeTodo(index)}>DELETE</button>
      
       </div>
    </div>
  
  );
}



CREATING TODO ITEMS WITH THE TODO FUNCTION

In the above function, you an see four parameters, namely todo, index, completeTodo and removeTodo. I will explain why we are using these variables first. 

The todo variable is used to store the item that we are adding everytime to the add button.


The index variable is used to store the index of each of the items that are added to the list so that we can manipulate the items by using the index number, that is, for example, do we need to manipulate the first item in the list, or the second item in the list and so on and so forth.


The variable, completeTodo is used to store all the todo items that we have done or completed in the list and need to keep a track of completed todo items in the list.
The variable removeTodo is used to store all the todo items that we need to remove from the list.


Inside this jsx function, we have directly injected the html for the ui. We have added a container, div, with a className of "todo" and in this jsx function, we have used double curly braces for the special expression and as you know, special expressions are allowed to use double curly braces to implement javascript functions right inside the jsx. By using the double curlies, we can inject the output of the html variables right inside this function. In this special expression, we are performing a conditional (ternary ) operator for executing the javaScript for the html style element in the jsx. We manipulate the text-decoration style property of the html element and using this ternary operator, we use strike-through style for the todo item if the todo item is completed and if not completed, then, just leave it as it is, if it is not a completed task in the list. Hence, we are able to perform the javaScript ternary operator operation directly inside the jsx. You may have noticed how we write the todo.text within a single curly braces inside this div container. By writing todo.text within the curly braces will actually output the value of the todo text inside the list, from the text that was added into the input field.

After this, we have one more div container, to carry two buttons, namely, the complete and the delete buttons. We add an onClick event arrow function to each of these buttons, that will execute the task of completing and deleting the todo task items upon implementing each of these arrow functions as shown above with reference to their respective index. The index reference here is very important or else, we end up removing all the items upon clicking the delete button or we may end up striking off all the items if we click the complete button, hence the importance of the index in this function.




CREATING THE TODO FORM

We create the form to add the todo items and for this we create a function TodoForm which takes a parameter addTodo as it's argument as this is the form that helps the user to add the new todo items and this function returns a form that can handle the items submitted to the form.

code for the TodoForm function

function TodoForm({addTodo}){
  const[value,setValue= React.useState('');
  const handleSubmit = e =>{
    e.preventDefault();
    if(!valuereturn;
    addTodo(value);
    setValue('');
  };
  return(
    <form onSubmit = {handleSubmit}>
      <input 
         type = 'text'
         className = 'input'
         value = {value}
         onChange = {e => setValue(e.target.value)}/>
    
    </form>
  
  );
}







In the above function we use the parameter, addTodo hereby, the useState hook in this React component, will help to initialize the state in the function component here. The useState generally accepts an initial state and returns two values, namely, the current state and a function that updates the state. In the code above, the first variable, value is the current state and the second variable, setValue is the function that is used to update the state. We set the initial state to an empty string, namely, React.useState(' ') 


The event.preventDefault() is a method that helps us to cancel an event if it is cancelable.This prevents the form in this case from getting refreshed every time and form submission becomes a smooth affair. Hence, it prevents a form from submitting, until and unless the submit button is clicked.


In the code, we write, if(!value) return.
What is the explanation for this, I am explaining here: This means, if the user is not adding any new item value to the input field, then, do not return the form with an empty item. If an item is added to the input , then the form will add the todo value and this is indiated by the code, addTodo(value) and hence the handleSubmit() method will help to ensure us that an empty item is not added to the form in the case when the user did not input any value and only returns a value of the todo if the user adds a value of a todo in the input field.
After adding new todo values, the form will be cleared once again to make space for adding new todo items. This is shown by the code :
setValue(' ')


On returning the form, inside the form, we write the handleSubmit within curly braces to implement the jsx for updating the values of the todo items. The handleSubmit function will receive and handle the data that the user is adding to the component.

The handleSubmit() is used to receive the data once the form is validated.


<form onSubmit = {handleSubmit}>
      <input 
         type = 'text'
         className = 'input'
         value = {value}
         onChange = {e => setValue(e.target.value)}/>
    
    </form>
  

In this code snippet, we are using JSX with special expression within curly braces to implement the values within the jsx itself.  Here the form is shown as an object inside the JSX in order to do the inline styling as well as implement the value of  the input items in the form . Hence the usage of the curly braces here in the code above. We are implementing the values of the html code for evaluating the values of the input items in the input element that has a type of 'text', and a value mentioned in curly braces for the value property as this will execute the value of the input right there itself inside the input of the form element.

The onChange()  function and event handler in React as shown in the above code,  is able to capture updated data whenever  there is any change in the input field. will be responsible for accessing and returning the current updated values of the items added in the target, in this case, the input box, and this event sets the value to the e.target.value


As we already mentioned earlier in the post, setValue() hooks in React us used to dynamically, validate and update the state of the form by keeping track of the item added or manipulated in the input box. This is how the setValue() hooks in the onChange function works 




CREATING OF THE  APP - APP FUNCTION

In the App function, we will be initiating the state of the todos const and also implementing the addTodo function to carry out the task of adding new todos to the list. We will be also implementing completeTodo and removeTodo functions in order to update the todos by marking the completed todos as completeTodo and removing the unwanted todos by clicking the removeTodo button.
So, inside the App component, we will add the Todo component with the updated values of the new todos and completed todos and removed todos and also the TodoForm component as well inside the App component. The TodoForm component will be showing the current values of the addTodo whenever the user inputs the new todos inside the form field.

In the App component, we will create a container to house the todo list and then use the map method to loop over all the individual todo items with reference to their index numbers whereby the JSX function will output the current updated values of the todos and also show the updated values of the completed and removed todos from the list.

code snippet for the function App()

function App(){
  const[todos,setTodos ] = React.useState([
    {text:'shop',
     isCompleted: false
    },
    {
     text:'book',
     isCompleted:false,
    },
    {

     text:'music',
     isCompleted:false
    }
  ]);

  const addTodo = text =>{
    const newTodos = [...todos,{text}];
  setTodos(newTodos);
  
  };
  const completeTodo = index =>{
    const newTodos =[...todos];
    newTodos[index].isCompleted = true;
    setTodos(newTodos);
  };
  const removeTodo = index =>{
    const newTodos = [...todos];
    newTodos.splice(index,1);
    setTodos(newTodos);
  };
  return(
    <div className = 'app'>
       <div className = 'todo-list'>
          {todos.map((todo,index)=>(
         <Todo
            key={index}
            index = {index}
            todo = {todo}
            completeTodo = {completeTodo}
            removeTodo = {removeTodo}/>
  ))}
         <TodoForm addTodo= {addTodo}/>
       </div>
    </div>
  
  );
}





USING THE STATE HOOK

In the functional component App, we have the useState hook to handle and manage the state in the App. It takes the initial value, that is the first argument in the constant, const[todos, setTodos], which is  todos and the second argument which is setTodos, that is responsible for setting the state, After the first render, it returns the the array with the todos where you will find the useState hook  sets the isCompleted to isFalse since we don't want the user to see the task as completed in the first load of the page itself. It is ideal that the todo be set to complete only after the user clicks on the complete button.




MAKING THE addTodo FUNCTION : ADDING THE TODOS

We perform the arrow function here to copy the items from the todos  text object using the spread operator ES6 and in the addTodo arrow function, we write the todos with the three dots, as they are the todos copied into this array  from the todo list , using the spread operator. Then we use the setTodos hook to update the state of the todos to the newTodos.


const addTodo = text =>{
    const newTodos = [...todos,{text}];
  setTodos(newTodos);
  
  };
  


STATE UPDATES

Make the updates to the states as explained below for complete

and deleted items.


UPDATE STATE OF TODO ITEMS AS COMPLETED ITEMS


onst completeTodo = index =>{
    const newTodos =[...todos];
    newTodos[index].isCompleted = true;
    setTodos(newTodos);
  }
  

In the above code snippet, we make the completeTodo function by creating the const completeTodo and using the arrow function , here, we are using the index as reference as we want to target each of the todo items in terms of their respective index number, so that , we could selectively update the respective todo items and not all the items! 

The variable const newTodos is going to store all the todos copied from the todo list, using the spread method and then, we are going to update the state by setting the value of the newTodos[index].isCompleted as true. When you set the isCompleted as true, what happens is that these items will be marked the status as completed items. We use the sestTodos hook to update the newTodos to the current updated value in real time.



UPDATE STATE OF TODO ITEMS TO DELETE OR REMOVE THE TODO ITEMS:


onst removeTodo = index =>{
    const newTodos = [...todos];
    newTodos.splice(index,1);
    setTodos(newTodos);
  }


In the above function we use const removeTodo as an arrow function to first copy the todos from the todo list to the array of the const newTodos using the spread operator, and then we use the splice method to remove the required item . 

In the splice method as you already know the first parameter is the index of the item that you want to have removed or deleted and the second parameter is the number of items that you want to remove. Here, we are using 1 as the second parameter as we aim to delete or remove one item at a time with reference to its respective index number. 

After that, we use the setTodos hook to update the state of the newTodos to the current updated value as in real time. So after the removal is carried out from the array, the resultant array would be devoid of the items that were removed from it!




MAKING THE TODO APP AND THE JSX 

return(
    <div className = 'app'>
       <div className = 'todo-list'>
          {todos.map((todo,index)=>(
         <Todo
            key={index}
            index = {index}
            todo = {todo}
            completeTodo = {completeTodo}
            removeTodo = {removeTodo}/>
  ))}

The App function returns a div container we give it a className of
'app' and then we make another container inside this div and give that
a className of 'todo-list. In this we loop over the todos using the
map method , with reference to the index. We take two parameters
inside the loop, the todo and the index as we want to map over the
todo items with reference to the respective index number of each
todo item.


We house the Todo component inside the App component. This
component has the following jsx elements, namely, the key with a
value of {index}, index with a value of {index} and todo with a
value of {todo} and completeTodo with a value of {completeTodo}
and removeTodo with a value of {removeTodo}. 

The reason we use double curly braces for above elements is to represent them as special jsx elements in React and by mentioning the elements within double curlies, we are able to output the values of the respective elements there itself in the JSX.

So, the Todo component witll show us the output of the current
values of the todo items with reference to their respective index and
also show the current updated values of completeTodo and
removeTodo .




RENDERING THE APP TO THE DOM

This is referred to as the ReactDOM.render() method and in this method, we will pass the JSX code to the root component of the app. This will render the React App to the web page. The first parameater in the code snippet below, is <App/>, that is what to render and the second paramaeater is , where to render and in this case, it is the container.

So, the first parameter is the element to render, in this case, the App and the second parameter is the container where it is to be rendered.
For rendering the app to the DOM, we need to write the following code snippet as shown below,  the first parameter is the component App, since that is the place where the app is rendering and the second parameter is the document.getElementById('container')


export default App;
ReactDOM.render(<App/>document.getElementById('container') );
 




THE CSS CODE FOR STYLING THE APP

The CSS code is quite simple here as you can see, with basic styling to the background and width and padding to the todo list and todo items as well as the button. This tutorial is more about the React and not going deep into the CSS part of the code, hence, I kept the CSS very basic and simple that you have already learnt in your starter journey of HTML and CSS.



.app {
  background: gray;
  height: 100vh;
  padding: 30px;
}

.todo-list {
  background: aqua;
  border-radius: 4px;
  max-width: 400px;
  padding: 5px;
}

.todo {
  align-items: center;
  background: #fff;
  border-radius: 3px;
  display: flex;
  font-size: 12px;
  justify-content: space-between;
  margin-bottom: 6px;
  padding: 3px 10px;
}
button{
  background:black;
  color:white;
  margin:10px;
}




THE FULL JAVASCRIPT CODE using React Hooks 


import React, {useStatefrom 'react';
import ReactDOM from 'react-dom';

function Todo({todo,index,completeTodo,removeTodo}){
  return(
    <div className = 'todo' style = {{ textDecoration: todo.isCompleted ? 'line-through ' : ''}}>
     {todo.text}
       <div>
         <button onClick = {() => completeTodo(index)}>COMPLETE</button>
         <button onClick = {() => removeTodo(index)}>DELETE</button>
      
       </div>
    </div>
  
  );
}

function TodoForm({addTodo}){
  const[value,setValue= React.useState('');
  const handleSubmit = e =>{
    e.preventDefault();
    if(!valuereturn;
    addTodo(value);
    setValue('');
  };
  return(
    <form onSubmit = {handleSubmit}>
      <input 
         type = 'text'
         className = 'input'
         value = {value}
         onChange = {e => setValue(e.target.value)}/>
    
    </form>
  
  );
}

function App(){
  const[todos,setTodos ] = React.useState([
    {text:'shop',
     isCompleted: false
    },
    {
     text:'book',
     isCompleted:false,
    },
    {

     text:'music',
     isCompleted:false
    }
  ]);

  const addTodo = text =>{
    const newTodos = [...todos,{text}];
  setTodos(newTodos);
  
  };
  const completeTodo = index =>{
    const newTodos =[...todos];
    newTodos[index].isCompleted = true;
    setTodos(newTodos);
  };
  const removeTodo = index =>{
    const newTodos = [...todos];
    newTodos.splice(index,1);
    setTodos(newTodos);
  };
  return(
    <div className = 'app'>
       <div className = 'todo-list'>
          {todos.map((todo,index)=>(
         <Todo
            key={index}
            index = {index}
            todo = {todo}
            completeTodo = {completeTodo}
            removeTodo = {removeTodo}/>
  ))}
         <TodoForm addTodo= {addTodo}/>
       </div>
    </div>
  
  );
}
export default App;
ReactDOM.render(<App/>document.getElementById('container') );



CONCLUSION

We finally built the Todo list App in React hooks with minimum lines of code.This app is able to accept new todo items in the form of text inputs and after that store the data in the todo list. If the user wants to mark some items as complete, then he can mark the items as completed and also able to remove or delete those items by using the remove button. 

Hence, this app can be considered as a CRUD app, meaning, the user can Create and add items, Read the added items, Update the items by marking them as completed items, and finally Delete the unwanted items from the list.


If you want to see the live view of the App, here is the app in the code editor of my choice, Jsitor, and below is the live app in action:
React Todo list App  


Other React Projects in my blog:



Comments

Popular Posts

Build A Random Quote Machine in React

A Simple Guide to Promises in JavaScript ES6

Build A Calculator in React

Welcome to my first Blog Post

How To Fight Programmer's Imposter Syndrome

Top Free Online Websites to Learn Coding

Guide to Learn Coding Efficiently and Effectively