Skip to main content

React CRUD using LocalStorage & Material UI

Follow the steps below : 

Install the following packages : 

npm install @mui/material @emotion/react @emotion/styled  

For using ICONS :

 npm i @mui/icons-material    

For Routing : 

npm i react-router-dom


FOLDER STRUCTURE should be like :




Routing will done at App.js : 

import Header from './components/Header'
import {
  BrowserRouter as Router,
  Routes,
  Route,
  Link
} from "react-router-dom";
import Home from './components/Home'
import Edit from './components/Edit'
import Add from './components/Add'

function App() {
  return (
    <>
      <Header />
      <Router>

        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/add" element={<Add />} />
          <Route path="/edit" element={<Edit />} />

        </Routes>

      </Router>

    </>
  )
}
export default App

At Home.js :

import { Button } from "@mui/material"
import { useEffect, useState } from "react"
import { useNavigate } from "react-router-dom"
import DeleteIcon from '@mui/icons-material/Delete'
import EditIcon from '@mui/icons-material/Edit';

function Home() {
    const navigate = useNavigate()
    const [blogs, setBlogs] = useState([])

    useEffect(() => {
        const blogs = localStorage.getItem('blogs')
        setBlogs(JSON.parse(blogs))
    }, [blogs])

    const handleDelete = (blogOutIndex) => {
        const _blogs = blogs.filter((blog, blogInIndex) => {
            if (blogInIndex !== blogOutIndex) {
                return blog
            }
        })
        console.log(_blogs)
        setBlogs(_blogs)
        localStorage.setItem('blogs', JSON.stringify(_blogs))
    }

    const handleEdit = (blogIndex) => {
        localStorage.setItem('editIndex', blogIndex)
        navigate('/edit')
    }



    return (
        <>
            <br />
            <Button
                onClick={() => {
                    navigate('/add')
                }}
                variant="contained" > ADD BLOG </Button>
            <br />

            {
                blogs && blogs.length > 0 ?
                    blogs.map((blog, blogIndex) => {
                        return (
                            <div style={{ borderBottom: "1px solid #eee", margin: '10px 0px' }}>
                                <span style={{
                                    display: 'inline-block',
                                    minWidth: '200px'
                                }}>
                                    {blog?.title} </span>
                                <span style={{
                                    display: 'inline-block',
                                    minWidth: '280px'
                                }}>
                                    {blog?.desc}
                                </span>
                                <EditIcon style={{ color: 'blue', minWidth: '50px' }} onClick={() => handleEdit(blogIndex)} ></EditIcon>
                                <DeleteIcon style={{ color: 'red' }} onClick={() => handleDelete(blogIndex)} ></DeleteIcon>
                            </div>
                        )
                    })
                    :
                    'No Data found'
            }
        </>
    )
}

export default Home


At Edit.js 


import { Button, TextField, Typography } from "@mui/material"
import { useState } from "react"
import { useNavigate } from "react-router-dom"


function Edit() {
    const navigate = useNavigate()
    const [title, setTitle] = useState('')
    const [desc, setDesc] = useState('')

    const handleTitleChange = (e) => {
        setTitle(e.target.value)
    }
    const handleDescChange = (e) => {
        setDesc(e.target.value)
    }


    const handleEdit = () => {
        console.log({ title, desc, index: localStorage.getItem('editIndex') })
        let blogs = localStorage.getItem('blogs') && localStorage.getItem('blogs').length > 0 ? JSON.parse(localStorage.getItem('blogs')) : []

        const _blogs = blogs.map((blog, blogInIndex) => {
            if (blogInIndex == localStorage.getItem('editIndex')) {
                return { title, desc }
            } else {
                return blog
            }
        })
        console.log(_blogs)
        localStorage.setItem('blogs', JSON.stringify(_blogs))
        navigate('/')
    }

    return (
        <>
            <Typography> Edit BLOG </Typography>
            <TextField value={title} onChange={(e) => handleTitleChange(e)} label="Title" variant="filled" /> <br />
            <TextField value={desc} onChange={(e) => handleDescChange(e)} label="Description" variant="filled" />
            <Button onClick={handleEdit} variant="contained" > SUBMIT </Button>

        </>
    )
}

export default Edit


At Add.js 


import { Button, TextField, Typography } from "@mui/material"
import { useState } from "react"
import { useNavigate } from "react-router-dom"



function Add() {
    const navigate = useNavigate()
    const [title, setTitle] = useState('')
    const [desc, setDesc] = useState('')

    const handleTitleChange = (e) => {
        setTitle(e.target.value)
    }
    const handleDescChange = (e) => {
        setDesc(e.target.value)
    }

    const handleSubmit = () => {
        console.log({ title, desc })

        const _blogs = localStorage.getItem('blogs') && localStorage.getItem('blogs').length > 0 ? JSON.parse(localStorage.getItem('blogs')) : []

        localStorage.setItem('blogs', JSON.stringify([..._blogs, { title, desc }]))

        navigate('/')
    }

    return (
        <>
            <Typography> ADD BLOG </Typography>
            <TextField value={title} onChange={(e) => handleTitleChange(e)} label="Title" variant="filled" /> <br />
            <TextField value={desc} onChange={(e) => handleDescChange(e)} label="Description" variant="filled" />   <br />
            <Button onClick={handleSubmit} variant="contained" > SUBMIT </Button>
        </>
    )
}

export default Add


And Finally for Header.js , You can use simple Heading or below code (Optional)


import * as React from 'react';
import { styled, alpha } from '@mui/material/styles';
import AppBar from '@mui/material/AppBar';
import Box from '@mui/material/Box';
import Toolbar from '@mui/material/Toolbar';
import IconButton from '@mui/material/IconButton';
import Typography from '@mui/material/Typography';
import InputBase from '@mui/material/InputBase';
import MenuIcon from '@mui/icons-material/Menu';
import SearchIcon from '@mui/icons-material/Search';

const Search = styled('div')(({ theme }) => ({
  position: 'relative',
  borderRadius: theme.shape.borderRadius,
  backgroundColor: alpha(theme.palette.common.white, 0.15),
  '&:hover': {
    backgroundColor: alpha(theme.palette.common.white, 0.25),
  },
  marginLeft: 0,
  width: '100%',
  [theme.breakpoints.up('sm')]: {
    marginLeft: theme.spacing(1),
    width: 'auto',
  },
}));

const SearchIconWrapper = styled('div')(({ theme }) => ({
  padding: theme.spacing(0, 2),
  height: '100%',
  position: 'absolute',
  pointerEvents: 'none',
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center',
}));

const StyledInputBase = styled(InputBase)(({ theme }) => ({
  color: 'inherit',
  '& .MuiInputBase-input': {
    padding: theme.spacing(1, 1, 1, 0),
    // vertical padding + font size from searchIcon
    paddingLeft: `calc(1em + ${theme.spacing(4)})`,
    transition: theme.transitions.create('width'),
    width: '100%',
    [theme.breakpoints.up('sm')]: {
      width: '12ch',
      '&:focus': {
        width: '20ch',
      },
    },
  },
}));

export default function SearchAppBar() {
  return (
    <Box sx={{ flexGrow: 1 }}>
      <AppBar position="static">
        <Toolbar>
          <IconButton
            size="large"
            edge="start"
            color="inherit"
            aria-label="open drawer"
            sx={{ mr: 2 }}
          >
            <MenuIcon />
          </IconButton>
          <Typography
            variant="h6"
            noWrap
            component="div"
            sx={{ flexGrow: 1, display: { xs: 'none', sm: 'block' } }}
          >
            CRUD REACT
          </Typography>
          <Search>
            <SearchIconWrapper>
              <SearchIcon />
            </SearchIconWrapper>
            <StyledInputBase
              placeholder="Search…"
              inputProps={{ 'aria-label': 'search' }}
            />
          </Search>
        </Toolbar>
      </AppBar>
    </Box>
  );
}



Check the video for further explaination : 





Comments

Popular posts from this blog

Shopping Cart React.js Project with Explanation✅ [ Simple Ecommerce Website using Reactjs ]

Hello guys in this video we will discuss shopping cart web app.  first we need to install the basic react app using - npx create-react-app app-name The folder structure should be containing three files  in components folder as below : In App.js :  import './App.css' ; import Header from './components/Header' ; import ProductList from './components/ProductList' ; import CartList from './components/CartList' ; import { useState } from 'react' ; function App () {   const [ product , setProduct ] = useState ([     {       url : 'https://rukminim1.flixcart.com/image/300/300/l51d30w0/shoe/z/w/c/10-mrj1914-10-aadi-white-black-red-original-imagft9k9hydnfjp.jpeg?q=70' ,       name : 'TRQ White Shoes' ,       category : 'Shoes' ,       seller : 'AMZ Seller Ghz' ,       price : 1999     },     {       url : 'https://5.imimg.com/data5/KC/PC/MY-38629861/dummy-chronograph-watch-500x500.jpg' ,       n

MERN Authentication - Login, Register, Verification Email, Forget Password, User Name & Logout on Navbar

In The React Side :  The folder structure will be : Lets start from App.js  On this file we will be adding routing , install the package react-router-dom : import './App.css' ; import React from 'react' ; import {   BrowserRouter as Router ,   Routes ,   Route ,   Link } from "react-router-dom" ; import Signup from './components/Signup' ; import Signin from './components/Signin' ; import Home from './components/Home' ; import ForgetPassword from './components/ForgetPassword' ; import NewSubmit from './components/NewSubmit' ; function App () {   return (     < div >       < Router >         < Routes >           < Route path = "/signup" element = { < Signup /> } />           < Route path = "/signin" element = { < Signin /> } />           < Route path = "/" element = { < Home /> } />           < Route

API Call In React JS using Axios [ React Form Submit To API ]

 Step 1 : npm i axios.  Step 2 : Create form with email and password.  Step 3 : create state to store email and password.  Step 4 : Store the value in state using onChange method.   Step 5 : Call the Api with data stored in state.   Step 6 : Handle Error and Success.   App.js Code below : import { useState } from "react" ; import './App.css' ; import axios from "axios" ; function App () {   const [ email , setEmail ] = useState ( '' )   const [ password , setPassword ] = useState ( '' )   console . log ({ email , password })   const handleEmail = ( e ) => {     setEmail ( e . target . value )   }   const handlePassword = ( e ) => {     setPassword ( e . target . value )   }   const handleApi = () => {     console . log ({ email , password })     axios . post ( 'https://reqres.in/api/login' , {       email : email ,       password : password     }). then ( result => {       console . log ( result .