DEV Community

Shirley
Shirley

Posted on

To Do List with React Hooks

React Hooks was introduced in Feb 2019 when React 16.8 was shipped. It allowed developers to use state and lifecycle methods inside functional components instead of purely class based components. Today, I am going to make a to-do list using useState() and show you guys how to use the most basic React hook, useState().
To make a todo app, we need to make a state hook, todos. We will declare this hook inside our App functional component.

function App () {
   const [todos, setTodos] = React.useState("")
}
Enter fullscreen mode Exit fullscreen mode

todos is the state variable, and setTodos is similar to this.setState where you can change the value of todos by setting setTodos equal to a value. You initialize the state by setting React.useState(""). If you want to set todos to a value, do this:

function App () {
   const [todos, setTodos] = React.useState([{text: "Do leetcode", isCompleted: false}])
}
Enter fullscreen mode Exit fullscreen mode

This sets todos equal to an array containing an object with keys of text and isCompleted and values equal to the content of the key.
Next, we want to make a function that adds a new todo to the todos variable.

const addTodos = (text) => {
     const newTodos = [...todos, {text:text, isCompleted:false}]
     setTodos(newTodos);

   }
Enter fullscreen mode Exit fullscreen mode

When you call setTodos, you set the todos variable equal to the newTodos variable.
Next, we want to have a function where we can cross an item off the list if it is completed. We use the isCompleted value in this case. We set the isCompleted property to equal true.

 const completeTodo = index => {
     const newTodos = [...todos];
     newTodos[index].isCompleted = true
     setTodos(newTodos)
   }
Enter fullscreen mode Exit fullscreen mode

The completeTodo function takes in an index parameter, which is the index of the todo that we want to cross off the list.

Finally, we want to remove a Todo from the list. We create a function for that and use splice to remove the selected todo.

 const removeTodo = index => {
     const newTodos = [...todos];
     newTodos.splice(index, 1)
     setTodos(newTodos)
   }
Enter fullscreen mode Exit fullscreen mode

Next, we want to create a form to input a todo and have it displayed on our list.

const TodoForm = ({addTodos}) => {
  const [value, setValue] = React.useState("")
  const handleSubmit=(e) => {
    e.preventDefault();
    if(!value) return;
    addTodos(value)
    setValue("")
  }
  return (
    <form onSubmit={handleSubmit}>
      <input className="input" type="text" value={value} placeholder="Add Todo" onChange={e => setValue(e.target.value)}/>
      <button type="submit">Add </button>
      </form>
  )
}
Enter fullscreen mode Exit fullscreen mode

The Todo form takes in a props in the form of addTodos. It has a state variable of value, which is what we use for the input. We have a handleSubmit() function that called e.preventDefault() to prevent the default form submission, and inside it, it calls addTodos(value) and setValue to empty after adding the todo. In our return, we set onChange of input equal to an inline function that takes in event and calls setValue(e.target.value).

Finally, we want to display our Todos:

const 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)} > X </button> 
      </div>
    </div>)
}
Enter fullscreen mode Exit fullscreen mode

The Todo function takes in todo props, index props, completeTodo props, and removeTodo props. If the todo's isCompleted property is true, there will be a line through the text. There will be two buttons, one for Completed, and one for removing the todo.
This is what the App function's return finally looks like:

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

Enter fullscreen mode Exit fullscreen mode

It calls the Todo functional component as well as the TodoForm functional component.

That's it for the app! Hope you guys enjoyed it, and let me know what content you want me to post in the future!

Top comments (0)