Click here to Skip to main content
15,878,959 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I'm new in React and state hooks.I'm trying to make a website about creating booklist and save it to local storage. Also uploading image to cloudinary. My problem is ; when i trying to save cloudinary image url to the localstorage, it saves previous url. I think i have a problem about useState , useEffect hooks but i couldnt figure it. Below is my code.

LocalStorage.js

JavaScript
import React, { useState, useEffect } from 'react'
import BookList from '../../components/BookList'
import CreateBook from '../../components/CreateBook'

const getLocalStorage = () => {
  let list = localStorage.getItem('liste')
  if (list) {
    return JSON.parse(localStorage.getItem('liste'))
  } else {
    return []
  }
}

const LocalStorage = () => {
  //state hooks
  const [list, setList] = useState(getLocalStorage)
  const [bookName, setBookName] = useState('')
  const [writerName, setWriterName] = useState('')
  const [pageNumber, setPageNumber] = useState('')
  const [info, setInfo] = useState('')
  const [image, setImage] = useState('')
  const [uploadUrl, setUploadUrl] = useState('')
  let id


  //Function for submit button
  const handleSubmit = async (e) => {
    e.preventDefault()
    // conditions for fill the blanks
    if (!bookName || !writerName || !pageNumber || !image) {
      setInfo('Please fill the blanks')
    } else {
      try {
        const data = new FormData()
        data.append('file', image)
        data.append('upload_preset', 'book-list-project')
        data.append('cloud_name', 'book-list')
        let response = await fetch(
          'https://api.cloudinary.com/v1_1/book-list/image/upload',
          {
            method: 'POST',
            body: data,
          }
        )
        let result = await response.json()
        setUploadUrl(result.url)
        id = new Date().getTime().toString()
        const newBook = {
          id: id,
          bookName: bookName,
          writerName: writerName,
          pageNumber: pageNumber,
          uploadUrl: uploadUrl,
        }

        setList([...list, newBook])
        setBookName('')
        setWriterName('')
        setPageNumber('')
        setInfo('Book created')
        setImage('')
      } catch (error) {
        console.log(error)
      }
    }
  }

  //Function for remove specific book from local storage
  const removeSpecificBook = (id) => {
    setList(list.filter((book) => book.id !== id))
  }

  // Function for clear all books from local storage
  const removeAllBooks = () => {
    setList([])
  }

  useEffect(() => {
    localStorage.setItem('liste', JSON.stringify(list))
  }, [list])

  return (
    <div>
      <CreateBook
        bookName={bookName}
        writerName={writerName}
        pageNumber={pageNumber}
        handleSubmit={handleSubmit}
        info={info}
        setBookName={setBookName}
        setWriterName={setWriterName}
        setPageNumber={setPageNumber}
        setImage={setImage}
      />

      <BookList
        items={list}
        removeSpecificBook={removeSpecificBook}
        removeAllBooks={removeAllBooks}
      />
    </div>
  )
}

export default LocalStorage


Booklist.js

JavaScript
import React from 'react'

const BookList = ({ items, removeSpecificBook, removeAllBooks }) => {
  return (
    <div className='container mx-auto'>
      <div className='mt-20 flex flex-wrap items-center justify-center'>
        {items.map((item) => {
          return (
            <div key={item.id} className='p-2 m-2 bg-yellow-100 w-1/4'>
              <div className='p-1 m-1 flex justify-center'>
                <img
                  className='object-contain h-52 w-52'
                  src={item.uploadUrl}
                  alt='some img'
                />
              </div>
              <div className='p-1 m-1'>
                <h5 className='font-semibold'>Book Name</h5>
                <h3>{item.bookName}</h3>
              </div>
              <div className='p-1 m-1'>
                <h5 className='font-semibold'>Writer Name</h5>
                <h3>{item.writerName}</h3>
              </div>
              <div className='p-1 m-1'>
                <h5 className='font-semibold'>Total Page</h5>
                <h3>{item.pageNumber}</h3>
              </div>
              <div className='flex justify-end'>
                <button
                  onClick={() => removeSpecificBook(item.id)}
                  className='px-4 py-2 bg-red-500 rounded-full text-white'
                >
                  Remove
                </button>
              </div>
            </div>
          )
        })}
      </div>
      {items.length > 1 && (
        <div className='flex justify-center my-5'>
          <button
            onClick={removeAllBooks}
            className='px-8 py-4 bg-red-500 rounded-full text-white'
          >
            Remove All
          </button>
        </div>
      )}
    </div>
  )
}

export default BookList


CreateBook.js

JavaScript
import React from 'react'

const CreateBook = ({
  bookName,
  writerName,
  pageNumber,
  handleSubmit,
  info,
  setBookName,
  setWriterName,
  setPageNumber,
  setImage,
}) => {
  return (
    <div>
      <div>
        <nav className='bg-blue-500  text-center text-white px-6 py-3'>
          Create Book
        </nav>
      </div>
      <div className='bg-red-200 mx-auto w-96 rounded-lg flex justify-center mt-20'>
        <form onSubmit={handleSubmit}>
          <div>
            <div className='p-3 text-center'>
              <h6>Enter Book Name</h6>
              <input
                value={bookName}
                onChange={(e) => setBookName(e.target.value)}
                className='rounded-md'
                type='text'
                placeholder='Book Name'
              />
            </div>
            <div className='p-3 text-center'>
              <h6>Enter Writer Name</h6>
              <input
                value={writerName}
                onChange={(e) => setWriterName(e.target.value)}
                className='rounded-md'
                type='text'
                placeholder='Writer Name'
              />
            </div>
            <div className='p-3 text-center'>
              <h6>Enter Total Page Number </h6>
              <input
                value={pageNumber}
                onChange={(e) => setPageNumber(e.target.value)}
                className='rounded-md'
                type='number'
                placeholder='Page Number'
              />
            </div>
            <div className='p-3 text-center'>
              <div>
                <h6>Upload Image</h6>
              </div>
              <div className='p-3'>
                <input
                  type='file'
                  onChange={(e) => setImage(e.target.files[0])}
                />
              </div>
            </div>
            <div className='flex justify-center p-3'>
              <button className='bg-blue-500 py-3 px-6 rounded-full text-white'>
                Submit
              </button>
            </div>
            <div className='p-3 text-center  text-white'>
              <h3>{info}</h3>
            </div>
          </div>
        </form>
      </div>
    </div>
  )
}

export default CreateBook


What I have tried:

Also please if you have any suggestions about my code structure, tell me. I dont have any programming history and trying to learn from beginning. I need every suggestions to go further learning programming. Thank you in advance.
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900