![]() |
| Todo List App in React with CRUD Operation and Locally Storing | Indiantechnoear |
Aim:
Create a Todo List app with React components that allows users to add, edit, view and delete tasks.
Component 1 | Main Part
| ToDoApp.js |
|---|
import React, { useEffect, useState } from 'react' import './ToDoApp.css'
// save data locally const getLocalData = () => { const lists = localStorage.getItem('ToDoApp') if (lists) { return JSON.parse(lists) } else { return [] } } const ToDo = () => { const [inputData, setInputData] = useState('') const [items, setItems] = useState(getLocalData()) const [isEditItem, setIsEditItem] = useState('') const [toggleButton, setToggleButton] = useState(false) document.title = 'ToDo App' // Convert text into sentence case function sentenceCase (str) { if (str === null || str === '') return false else str = str.toString() return str.replace(/\w\S*/g, function (txt) { return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase() }) } // item add function const addItem = () => { if (!inputData) { alert('Enter items then add.') } else if (inputData && toggleButton) { setItems( items.map(curElem => { if (curElem.id === isEditItem) { return { ...curElem, name: inputData } } return curElem }) ) setInputData('') setIsEditItem(null) setToggleButton(false)
} else { const NewInputData = { id: new Date().getTime().toString(), name: inputData } setItems([...items, NewInputData]) setInputData('') //clear input add item } } // edit item const editItem = index => { const editedItem = items.find(curElem => { return curElem.id === index }) setInputData(editedItem.name) setIsEditItem(index) setToggleButton(true) } // delete item function const deleteItem = index => { const updatedItem = items.filter(curElem => { return curElem.id !== index }) setItems(updatedItem) } //clear all items const removeAll = () => { setItems([]) } // data store in local storage useEffect(() => { localStorage.setItem('ToDoApp', JSON.stringify(items)) }, [items]) // add on click enter const handleKeypress = event => { //it triggers by pressing the enter key if (event.keyCode === 13) { addItem() } } return ( <> <div className='main-div'> <div className='child-div'> <div className='head-hero'> <h3> To Do <br></br>Application </h3> <i className='fa fa-list fa-4x'></i> </div> <div className='add-items'> <input title='Add items' type='text' placeholder='✒️Add items now....' className='form-control' value={inputData} onChange={event => setInputData(event.target.value)} onKeyPress={handleKeypress} /> {toggleButton ? ( <i title='Save the edit' className='fa fa-edit add-btn add-on-click ' onClick={addItem} ></i> ) : ( <i title='Save the item' className='fa fa-plus add-btn add-on-click plus-icon' onClick={addItem} ></i> )} </div> {/* show items */} <div className='show-item'> {items.map((curElem, index) => { return ( <div className='each-item' key={curElem.id}> <p>{sentenceCase(curElem.name)}</p> <div className='todo-btn'> <i title='Edit this item' className='fa fa-edit add-btn' onClick={() => editItem(curElem.id)} ></i> <i title='Delete this item' className='fa fa-trash-alt add-btn' onClick={() => deleteItem(curElem.id)} ></i> </div> </div> ) })} </div> {/* remove button */} <div className='show-item'> <button title='Clear All Items' className='btn effect04 clear-btn' data-sm-link-text='Remove All' onClick={removeAll} ><span>X</span> </button> </div> </div> </div> </> ) } export default ToDo; |
Component 2 | CSS Part
| ToDoApp.css |
|---|
body {background-color: #000;color: #fff} .main-div {background-color: #000;color: #fff;height: 100%;width: 100%;display: flex;position: absolute;justify-content: center;text-align: center} .child-div {padding: 20px;border-radius: 15px;margin-top: 50px;box-sizing: initial;width: 400px;height: 100%} .head-hero {display: flex;align-items: center;text-align: left;font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;border-left: 2px solid;justify-content: space-between;padding-left: 10px;margin-bottom: 20px} .head-hero>.fa:hover {color: #fff;cursor: unset} .add-items {display: flex;align-items: center;color: red;overflow: hidden;justify-content: space-between;margin: 5px;margin-bottom: 20px;background-color: #fff;border-radius: 10px;border: 2px solid #000} .add-items:hover {border: 2px solid blue;background-color: blue;-webkit-box-shadow: 0 0 5px 2px #fff;-moz-box-shadow: 0 0 5px 2px #fff;box-shadow: 0 0 5px 5px #fff} .plus-icon:hover {color: #fff} .plus-icon:active {color: #000;font-weight: 700} .form-control {font-weight: bolder;height: 55px;border: none}.each-item {color: #fff;display: flex;padding: 10px;margin: 5px;justify-content: space-between;background-color: #fff;color: #000;border-radius: 10px;font-weight: 700;height: 55px;font-family: Georgia, 'Times New Roman', Times, serif} .each-item:hover {background-color: blue;color: #fff;border-radius: 10px;transition: .2s} .show-item {color: #fff;justify-content: center}.todo-btn {color: red;margin-right: -9px} .todo-btn>.fa:hover {color: #fff} .todo-btn>.fa:active {color: #000} .btn {background-color: #fff;border-radius: 5px} .btn:hover {background-color: blue} .fa {cursor: pointer;padding: 10px;right: 0;text-align: right} .clear-btn {border-radius: 50%;color: #f00000;font-size: 30px;height: 50px;width: 50px;display: contents;align-items: center;justify-content: center} .add-on-click:hover {color: #fff} .ad-on-click:active {color: #000} |
Component 3 | Index Part
| index.js |
|---|
import ReactDOM from 'react-dom/client' import ToDo from './ToDoApp' const root = ReactDOM.createRoot(document.getElementById('root')) root.render( <> <ToDo /> </> ) |
Output:
