DEV Community

loading...
Cover image for React for beginners

React for beginners

purohitdheeraj profile image Dheeraj Purohit ・5 min read

Hello today we are going to build a todo list app in react by which you can understand basics of react how it works

we can use code sandbox CodeSandbox here to get started with react it provides an template to build our web apps faster.

To start with your todo app create a new sandbox by selecting react template.


After creating an sandbox react-template checkout how files are organized in react and this structure is going to be common in react.

App.js

import "./styles.css";

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

For our todo list application all our code is to be done in app.js.

So Let's Get Started...

1) Adding Input Element to our App

App.js

import "./styles.css";

export default function App() {
  return (
    <div className="App">
       // heading
        <div className="heading">
          <h1>TO-DO App</h1>
       </div>


      // form element to take input from user

        <form className="formtodo">
          <input placeholder="Enter Your Text Here..."
            type="text"
            id="todoValue"
          ></input>
          <button type="submit">Add Todo</button>
        </form>


    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

2) Adding onChange and onSubmit to input

App.js

import "./styles.css";

export default function App() {

function handleSubmit(){
// event handler function
}

function changeHandler(e){
// event handler function
}

return (
    <div className="App">
       // heading
        <div className="heading">
          <h1>TO-DO App</h1>
       </div>


      // form element to take input from user
      // adding onSubmit and onChange event listener.

        <form className="formtodo" onSubmit={handleSubmit}>
          <input 
            onChange={changeHandler}
            placeholder="Enter Your Text Here..."
            type="text"
            id="todoValue"
          ></input>
          <button type="submit">Add Todo</button>
        </form>


    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

Here we have declared two event listener method onChange and onSubmit to handle user input and these event listener method will call event handler functions to further process the input of user.

3) Adding useState hook

What is a hook? hook is an special function which allow us to add and update state variables.so here we are going to use useState hook to store and update our list of tasks.

App.js

import "./styles.css";
import {useState} from 'react';

export default function App() {
const [todoValue, setTodoValue] = useState('');
const [todos, settodos] = useState([]);

function handleSubmit(event){
// event handler function
event.preventDefault(); // this will prevent default behaviour of form on submit
}

function changeHandler(event){
// event handler function
setTodoValue(event.target.value);
}

return (
    <div className="App">
       // heading
        <div className="heading">
          <h1>TO-DO App</h1>
       </div>


      // form element to take input from user
      // adding onSubmit and onChange event listener.

        <form className="formtodo" onSubmit={handleSubmit}>
          <input 
            onChange={changeHandler}
            placeholder="Enter Your Text Here..."
            type="text"
            id="todoValue"
          ></input>
          <button type="submit">Add Todo</button>
        </form>


    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

We are taking current input value by (event.target.value) and assigning that current input value to state variable (setTodoValue) in changeHandler function

4) Add Task

App.js

import "./styles.css";
import {useState} from 'react';

export default function App() {
const [todoValue, setTodoValue] = useState('');
const [todos, settodos] = useState([]);

function handleSubmit(event){
// event handler function
event.preventDefault(); // this will prevent default behaviour of form on submit

if (todoValue === undefined ||
    todoValue === "" ||
    todoValue?.trim() === ""){
      alert("You are lazy!!! enter proper value.");
    }else {
        const todo = {
        value: todoValue,
        done: false
      };

      // spreading of previous value of todos
      settodos([...todos, todo]);
      document.getElementById("todoValue").value = "";
      // console.log(todoValue);
      settodoValue("");
      // console.log(todoValue)
    }


}

function changeHandler(event){
// event handler function
setTodoValue(event.target.value);
}

return (
    <div className="App">
       // heading
        <div className="heading">
          <h1>TO-DO App</h1>
       </div>


      // form element to take input from user
      // adding onSubmit and onChange event listener.

        <form className="formtodo" onSubmit={handleSubmit}>
          <input 
            onChange={changeHandler}
            placeholder="Enter Your Text Here..."
            type="text"
            id="todoValue"
          ></input>
          <button type="submit">Add Todo</button>
        </form>

       <div className="output">
        {todos &&
          todos.map((task, i) => {
            return (
              <div className="todo-list" key={task.value} id={i}>
                <button>
                  {task.value}
                </button>              
              </div>
            );
          })}
      </div>

   </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

we are taking input value by (event.target.value) and assigning that value to state variable(setTodoValue(e.target.value)).on submit of task handleSubmit function will be called and will check for blank values if not then it will make an object of keys(value,done)in else block of handleSubmit function and add that to state array using settodos([...todos,todo])spreading of array method.

For displaying our task-list mapping of todos array is done.
for other operation like line-through and delete we need to access the index {i} while mapping through todos array.

5)Delete Task and line-through it

App.js

import "./styles.css";
import { useState } from "react";
export default function App() {
  const [todoValue, settodoValue] = useState("");

  const [todos, settodos] = useState([]);

  const handleDone = (e) => {
    const { id } = e.target.parentElement;
    todos[id].done = !todos[id].done;
    // console.log(todos[id].done, todos[id].value);
    settodos([...todos]);
  };

  function handleSubmit(e) {
    e.preventDefault();

    if (
      // todoValue === <strong>[&rlm;&rlm;&lrm;]</strong> ||
      // todoValue?.trim() == " ‏‏‎ " ||

      todoValue === undefined ||
      todoValue === "" ||
      todoValue?.trim() === ""
    ) {
      alert("You are lazy!!! enter proper value.");
    } else {
      const todo = {
        value: todoValue,
        done: false
      };
      // spreading of previous value of todos
      settodos([...todos, todo]);
      document.getElementById("todoValue").value = "";
      // console.log(todoValue);
      settodoValue("");
      // console.log(todoValue)
    }
  }

  function hanleDelete(e) {
    const { id } = e.target.parentElement;
    console.log(id);
    console.log(e.target.parentElement);
    todos.splice(id, 1);
    settodos([...todos]);
  }

  function changeHandler(event) {
    settodoValue(event.target.value);
    // console.log(event.target.value);
  }

  return (
    <div className="App">
      <div className="heading">
        <h1>TO-DO App</h1>
      </div>

      <div>
        <form className="formtodo" onSubmit={handleSubmit}>
          <input
            placeholder="Enter Your Text Here..."
            type="text"
            id="todoValue"
            onChange={changeHandler}
          ></input>

          <button type="submit">Add Todo</button>
        </form>
      </div>

      <div>
        {todos &&
          todos.map((task, i) => {
            return (
              <div className="todo-list" key={task.value} id={i}>
                <button
                  // if task.done is true then apply "done"  to classname else apply "not-done".. task.done will be changed to true on click over it

                  className={task.done ? "done" : "not-done"}
                  onClick={handleDone}
                >
                  {task.value}
                </button>
                {/* {task.value} */}
                <button onClick={hanleDelete}>Delete</button>
              </div>
            );
          })}
      </div>
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

For Delete operation on click button will call handle delete and this event handler function takes task id and it uses splice method to remove that cliked {id} Task from the array and it updates the todos array after splice method.

For line-through operation on click button will call handleDone and in that function it will toggle the key "done:false" to its opposite value"done:true" and reset that change "done" value to todo array by settodos([...todos]).for this operation we have defined conditional className and used css line-through property.

Style.css

@import url("https://fonts.googleapis.com/css?family=Roboto+Condensed:300i,400,400i,700");

* {
  padding: 0;
  margin: 0;
}

.heading {
  color: #332d36;
  font-weight: 300;
  font-size: 2.5rem;
  text-align: center;
}
body {
  background: skyblue;
}

.App {
  font-family: sans-serif;
  text-align: center;
  /* background: skyblue; */
  padding: 1rem;

  font-family: "Roboto Condensed", sans-serif;
}

button,
input {
  all: unset;
  color: blue;
  -webkit-text-fill-color: blue;
  cursor: pointer;
}

.done {
  text-decoration: line-through;
}

input {
  padding: 1rem;
  border-radius: 5px;
  text-align: left;
  cursor: text;
  background: whitesmoke;
  /* outline-width: 0.1rem; */
  box-shadow: 1px 2px 5px 1px;
}

[type="submit"] {
  padding: 1rem;
  margin-left: 0.5rem;
  background: whitesmoke;
  border-radius: 10px;

  box-shadow: 1px 4px 1px 1px;
}

[type="submit"]:active {
  box-shadow: 1px 2px 1px 1px;
}
.todo-list {
  background: wheat;
  padding: 1rem;
  margin: 1rem auto;
  border-radius: 10px;
  max-width: 500px;
  width: 100%;
  /* overflow: scroll; */
  display: grid;
  grid-template-columns: 4fr 1fr;
}

.formtodo {
  /* background: whitesmoke; */
  padding: 1rem;
  margin: 1rem auto;
  max-width: 550px;
  display: grid;
  grid-template-columns: 4fr 1fr;
}

.not-done,
.done {
  border-radius: 10px 0 0 10px;
  border: none;
  text-align: left;
  padding: 1rem;
}

Enter fullscreen mode Exit fullscreen mode

So that's complete our todo list app , sharing my codesandbox link for your reference.

Discussion (2)

Collapse
urielbitton profile image
Collapse
purohitdheeraj profile image
Dheeraj Purohit Author

Glad you liked it 🙏🙏 thank you 😊

Forem Open with the Forem app