How to properly conditionally render child component in react - javascript

I have the following components : (AddBookPanel contains the AddBookForm)
I need to have the ability to display the form on click of the 'AddBookButton', and also
have the ability to hide the form while clicking the 'x' button (img in AddBookForm component), however the component doesn't seem to load properly, what could be wrong here? What do you think is the best way to organize this?
import { AddBookButton } from './AddBookButton';
import { AddBookForm } from './AddBookForm';
import { useState } from 'react';
export const AddBookPanel = () => {
const [addBookPressed, setAddBookPressed] = useState(false);
return (
<div>
<div onClick={() => setAddBookPressed(!addBookPressed)}>
<AddBookButton />
</div>
<AddBookForm initialFormActive={addBookPressed} />
</div>
);
};
import { useState } from 'react';
interface AddBookFormProps {
initialFormActive: boolean;
}
export const AddBookForm: React.FC<AddBookFormProps> = ({
initialFormActive,
}) => {
const [isFormActive, setIsFormActive] = useState(initialFormActive);
return (
<>
{isFormActive && (
<div className="fixed box-border h-2/3 w-1/3 border-4 left-1/3 top-24 bg-white border-slate-600 shadow-xl">
<div className="flex justify-between bg-slate-400">
<div>
<p className="text-4xl my-5 mx-6">Add a new Book</p>
</div>
<div className="h-16 w-16 my-3 mx-3">
<button onClick={() => setIsFormActive(!isFormActive)}>
<img
src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a0/OOjs_UI_icon_close.svg/1200px-OOjs_UI_icon_close.svg.png"
alt="close-button"
className="object-fit"
></img>
</button>
</div>
</div>
<div className="flex-col">
<div className="flex justify-between my-10 ml-5 text-xl">
<input type="text" placeholder="book name"></input>
</div>
</div>
</div>
)}
</>
);
};

You're always rendering the AddBookForm. That means in the initial render the useState is called with false. Since you never call setIsFormActive it is now stuck as "do not render".
Just don't use the useState and use the property initialFormActive directly. And maybe rename it to isFormActive. Let the parent handle the state change.
import { AddBookButton } from './AddBookButton';
import { AddBookForm } from './AddBookForm';
import { useState } from 'react';
export const AddBookPanel = () => {
const [addBookPressed, setAddBookPressed] = useState(false);
return (
<div>
<div onClick={() => setAddBookPressed(!addBookPressed)}>
<AddBookButton />
</div>
<AddBookForm initialFormActive={addBookPressed} onClose={() => setAddBookPressed(false)} />
</div>
);
};
import { useState } from 'react';
interface AddBookFormProps {
initialFormActive: boolean;
onColse: () => void;
}
export const AddBookForm: React.FC<AddBookFormProps> = ({
initialFormActive,
onClose,
}) => {
// const [isFormActive, setIsFormActive] = useState(initialFormActive); don't use this frozen state, allow the parent to control visibility
return (
<>
{initialFormActive && (
<div className="fixed box-border h-2/3 w-1/3 border-4 left-1/3 top-24 bg-white border-slate-600 shadow-xl">
<div className="flex justify-between bg-slate-400">
<div>
<p className="text-4xl my-5 mx-6">Add a new Book</p>
</div>
<div className="h-16 w-16 my-3 mx-3">
<button onClick={() => onClose()}>
<img
src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a0/OOjs_UI_icon_close.svg/1200px-OOjs_UI_icon_close.svg.png"
alt="close-button"
className="object-fit"
></img>
</button>
</div>
</div>
<div className="flex-col">
<div className="flex justify-between my-10 ml-5 text-xl">
<input type="text" placeholder="book name"></input>
</div>
</div>
</div>
)}
</>
);
};

Problem with your code is in how you tied initialFormActive to inner state of AddBookForm component. When looking at useState inside AddBookForm it is clear that prop initialFormActive only affects your initial state, and when looking at your parent component I can clearly see that you passed false as value for initialFormActive prop, thus initializing state inside AddBookForm with false value(form will stay hidden). Then you expect when you click on button, and when prop value changes(becomes true), that your <AddBookForm /> will become visible, but it will not because you just used initial value(false) from prop and after that completely decoupled from prop value change.
Since you want to control visibility outside of component, then you should attach two props to AddBookForm, isVisible and toggleVisibiliy. And do something like this:
export const AddBookPanel = () => {
const [addBookPressed, setAddBookPressed] = useState(false);
const toggleAddBookPressed = () => setAddBookPressed(p => !p);
return (
<div>
<div onClick={() => setAddBookPressed(!addBookPressed)}>
<AddBookButton />
</div>
<AddBookForm isVisible={addBookPressed} toggleVisibility={toggleAddBookPressed } />
</div>
);
};
export const AddBookForm: React.FC<AddBookFormProps> = ({
isVisible, toggleVisibility
}) => {
return (
<>
{isVisible&& (
<div className="fixed box-border h-2/3 w-1/3 border-4 left-1/3 top-24 bg-white border-slate-600 shadow-xl">
<div className="flex justify-between bg-slate-400">
<div>
<p className="text-4xl my-5 mx-6">Add a new Book</p>
</div>
<div className="h-16 w-16 my-3 mx-3">
<button onClick={toggleVisibility}>
<img
src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a0/OOjs_UI_icon_close.svg/1200px-OOjs_UI_icon_close.svg.png"
alt="close-button"
className="object-fit"
></img>
</button>
</div>
</div>
<div className="flex-col">
<div className="flex justify-between my-10 ml-5 text-xl">
<input type="text" placeholder="book name"></input>
</div>
</div>
</div>
)}
</>
);
};

Related

How to get child click on paremt in react js

I have a child and parent compoinents as follows,
When I click on the div I am not able to get the alert in parent component but when I keep button in child component I can able to get the aler. Not sure what I am doing, Can any one please help. Thanks.
Child Comp:
const PrimaryNavigation = ({ className, data, childToParent }: IPrimaryNavigation) => {
return (
<div className={`${className} w-full bg-black grid grid-cols-12 gap-4 py-12 pl-12`}>
<div className="relative col-span-2 md:col-span-1 w-5 h-5 md:w-6 md:h-6 cursor-pointer" onClick={() => { childToParent() }}>>
<Image src={searchSvg} layout="fill" objectFit="contain" alt="hamburgerIcon" />
</div>
<div className="relative col-span-2 md:col-span-1 md:w-6 md:h-6 w-5 h-5 cursor-pointer" >
<Image src={hamburgerSvg} layout="fill" objectFit="contain" alt="searchIcon" />
</div>
</div>
)
}
Parent Comp:
const Header = ({ data }: IHeader) => {
const childToParent = () => {
alert('hi')
}
return (
<div>
<header className="w-full md-0 md:md-6 bg-black grid grid-cols-12 gap-4">
<PrimaryNavigation className="col-span-11" data={data.primaryNavigationCollection.items} childToParent={childToParent} />
</header>
</div>
)
}
export default Header

Button Function Not calling From Another file in React

I need to call CutomerDashboard.js file's "toggleIsTrucated" function and "isTruncated" to CustomerNotice.js files button onClick and text change places, How can I call that?
(In this customer dashboard file I'm creating a Read function to show some extent of notice text)
import React, {useState,useEffect} from 'react';
import { Input, Row, Col, Button } from 'antd';
import {fetchDashboardMetrics} from "./DashboardApi";
import {items} from "./DashboardItems";
import axios from 'axios';
import CustomerNotice from "./CustomerNotice";
function Read ({children}) {
const text = children;
const [isTruncated, setIsTrucated] = useState(true);
const result = isTruncated ? text.slice(0,90) : text;
function toggleIsTrucated(){
setIsTrucated(!isTruncated);
}
return (
<div>
{result}....
</div>
);
}
const CustomerDashboard = () => {
const [features, setFeatures] = useState(items);
const source = axios.CancelToken.source()
const [notice, setNotice] = useState(<Read>Customer Notice: Optimism Is Invaluable For The Meaningful Life. With A Firm Belief In A Positive Future You Can Throw Yourself Into The Service Of That Which Is Larger Than You Are. -Martin Seligman-</Read>);
const [noticeVisibility, setNoticeVisibility] = useState(true);
useEffect(() => {
fetchDashboardMetrics(features, setFeatures,source.token)
return (() => {
source.cancel();
})
}, []);
return (
<>
<div className='md:pl-8 sm:pl-0'>
<div className='my-5 '>
<p className='mb-8'>My Account - Dashboard Overview</p>
{noticeVisibility && <CustomerNotice notice={notice} setNoticeVisibility={setNoticeVisibility}/>}
</div>
<ul role="list" className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
{features.map((feature) => (
<li key={feature.name} className="col-span-1 bg-white rounded-lg shadow divide-y divide-gray-200 relative">
<div className="w-full flex items-center justify-between p-6 space-x-6">
<div className="flex-1 truncate">
<div className="flex items-center space-x-3 justify-between">
<h3 className="text-gray-900 text-lg truncate">{feature.name}</h3>
{feature.isNew && (
<div className="absolute -top-2 -right-2 p-1 px-4 text-white text-sm bg-red-500">
New
</div>
)}
</div>
</div>
</div>
<div>
<div className={'mx-4 mt-2 mb-3 '}>
{feature.details.map((singleDetail) => {
return (
<div className={'flex justify-between text-base'}>
<span>{singleDetail.name}</span>
<span>{singleDetail.value}</span>
</div>
)
})}
</div>
</div>
</li>
))}
</ul>
</div>
</>
)
}
export default CustomerDashboard;
import React, {useState,useEffect} from 'react';
import {XIcon} from "#heroicons/react/solid";
const CustomerNotice = ({notice, setNoticeVisibility}) => {
return (
<div>
<div className="mt-8 pb-2 sm:pb-5">
<div className="max-w-7xl mx-auto px-2 sm:px-6 lg:px-8">
<div className="p-2 rounded-lg bg-orange-600 shadow-lg sm:p-3">
<div className="flex items-center justify-between flex-wrap">
<div className="w-0 flex-1 flex items-center">
<p className="ml-3 font-medium text-white truncate">
<span className="md:inline">{notice}</span>
</p>
</div>
<div className="order-3 mt-2 flex-shrink-0 w-full sm:order-2 sm:mt-0 sm:w-auto">
<a
href="#"
className="flex items-center justify-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-orange-600 bg-white hover:bg-orange-50"
>
<button onClick={toggleIsTrucated}>{isTruncated ? "Read More" : "Read Less"}</button>
</a>
</div>
<div className="order-2 flex-shrink-0 sm:order-3 sm:ml-2">
<button
onClick={() => setNoticeVisibility(false)}
type="button"
className="-mr-1 flex p-2 rounded-md hover:bg-orange-500 focus:outline-none focus:ring-2 focus:ring-white"
>
<span className="sr-only">Dismiss</span>
<XIcon className="h-6 w-6 text-white" aria-hidden="true"/>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
);
};
export default CustomerNotice;
If this is not possible please suggest me a possible way.
Instead of doing a bunch of hacks, I would recommend simplifying the structure of your components.
import { useState } from 'react'
export default function CustomerDashboard() {
// I am not sure why you want to keep notice in state,
// because in your example you did not call setNotice
const [notice, setNotice] = useState(`
Customer Notice: Optimism Is Invaluable For The Meaningful Life.
With A Firm Belief In A Positive Future You Can Throw Yourself Into The Service
Of That Which Is Larger Than You Are. -Martin Seligman
`)
const [isNoticeVisible, setIsNoticeVisible] = useState(true)
return (
<div>
<h1>My Account - Dashboard Overview</h1>
{isNoticeVisible && (
<CustomerNotice
notice={notice}
setIsNoticeVisible={setIsNoticeVisible}
/>
)}
</div>
)
}
function CustomerNotice(props) {
const { notice, setIsNoticeVisible } = props
const [isTruncated, setIsTruncated] = useState(true)
function toggleIsTruncated() {
setIsTruncated(!isTruncated)
}
return (
<div>
<Read text={notice} isTruncated={isTruncated} />
<button onClick={toggleIsTruncated}>
{isTruncated ? 'Read More' : 'Read Less'}
</button>
<button onClick={() => setIsNoticeVisible(false)}>Dismiss</button>
</div>
)
}
function Read(props) {
const { text, isTruncated } = props
const result = isTruncated ? text.slice(0, 90) : text
return <div>{result}....</div>
}
List of the things that were bad in your code.
Keeping the component instance in the state. It is hard to manage. Even your simple case proves that.
Keeping the toggleIsTruncated function inside the Read component. I think we should keep it outside and pass only 2 props to the Read component. I enable exposed only two things
const { text, isTruncated } = props
As you can see it is easy to maintain and allow us to do whatever we want.
PS. If my review and example were helpful please leave the thumbs up.

How to pass an icon as a prop?

I'm using props and I want to have "optionText" and "optionIcon" the 1st one I'm able to add but I'm not able to implement an icon as a prop
File where I'm creating props
import Icon from "#mui/material/Icon";
function HeaderMenuOptions({ optionText, OptionIcon }) {
return (
<div className="flex items-center text-center">
<Icon>{OptionIcon}</Icon>
<h1 className="py-1 my-1 hover:bg-menu-option-hover hover:text-black cursor-pointer">
{optionText}
</h1>
</div>
);
}
export default HeaderMenuOptions;
file where I'm using said props
<div className="absolute left-72 top-3 rounded-md bg-section w-[10rem] text-center">
<p className="menu-header mt-2">VIEW OPTIONS</p>
<div className="flex items-center justify-center space-x-2 mr-2 cursor-pointer hover:bg-menu-option-hover hover:hover:text-black group">
<HeaderMenuOptions optionText="Night Mode" />
<CheckBoxIcon
defaultChecked
onClick={() => alert("Light mode has not been added yet!")}
className="cursor-pointer text-blue-500"
/>
</div>
<p className="menu-header">MORE STUFF</p>
<HeaderMenuOptions optionText="Premium" OptionIcon={SecurityIcon} />
<HeaderMenuOptions optionText="TEST" />
<HeaderMenuOptions optionText="TEST" />
<HeaderMenuOptions optionText="TEST" />
<HeaderMenuOptions optionText="TEST" />
</div>
can anyone please help me. Thanks
The HeaderMenuOptions looks fine. You need to change the parent component.
You can do something like this.
<HeaderMenuOptions optionText="Premium" OptionIcon={<SecurityIcon />} />
You can use pass icon as JSX.Element from ParentComponent to TargetComponent as the following:
import AddAlertIcon from '#mui/icons-material/AddAlert';
...
const ParentComponent=()=>{
return(
....
<TargetComponent icon={<AddAlertIcon />}>
....
)
}
const TargetComponent = (props: Props) => {
return(
<span>
{props.icon}
</span>
);
}
export type Props= {
icon: JSX.Element;
};

|React:useOutsideClick hook gives forwardRef warning message

From firebase I fetch data and map this data to be shown in cards, every card has edit component and CardComponent(edit component parent) which use ref provided from useHandleOpen custom hook
Error message:
Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
Component where ref is in use
export default function EditCard(id) {
const { ref, isOpen, setIsOpen } = useHandleOpen(false);
return (
<div>
<GoKebabVertical
ref={ref}
className="cursor-pointer "
onClick={() => setIsOpen(true)}
/>
{isOpen && (
<div
ref={ref}
className="w-20 h-15 bg-white z-30 rounded-md absolute text-center
top-0 right-0
"
>
<p className="hover:bg-blue-300 hover:text-white cursor-pointer">
Edytuj
</p>
<p
className="bg-red-400 text-white font-semibold hover:bg-red-600 cursor-pointer"
onClick={() => {}}
>
UsuĊ„
</p>
</div>
)}
</div>
);
}
export const Edit = memo(EditCard);
Card component which use ref tho and its Edit parent
const Card = ({ data, id }) => {
const editRef = useRef(null);
const { ref, isOpen, setIsOpen } = useHandleOpen(editRef);
return (
<div
className="bg-gradient-to-r from-blue-200 to-purple-500
w-64 h-28 rounded-md relative
"
>
<div className="relative top-0 left-0">
<p className="px-2 pt-1 font-bold text-gray-800 text-lg">
{data.subject_name}
</p>
<p className="px-2 text-xs text-gray-800">Sala 101</p>
</div>
<div
className="absolute top-0 right-0 rounded-r-md
rounded-b-none
bg-white w-6 h-7
grid place-items-center
"
>
<Edit id={id} />
</div>
<div className="absolute bottom-9 left-0 mb-2.5">
<p className="px-2 text-xs text-gray-800">{data.teacher}</p>
</div>
<div className=" flex direction-row mt-7 text-center w-full justify-end align-bottom pr-2 ">
<div className="rounded-lg w-14 h-7 mx-3 bg-purple-300">
<a
href={data.link_subject}
className="text-gray-800
"
target="_blank"
rel="noreferrer"
>
Lekcja
</a>
</div>
<div className="rounded-lg w-14 h-7 bg-gray-800 ">
<a
href={data.link_online_lesson}
target="_blank"
rel="noreferrer"
className="text-white"
>
Online
</a>
</div>
</div>
<div
className=" absolute bottom-0 left-0 rounded-l-md
bg-white w-7 h-6 grid place-items-center devide-solid"
>
{isOpen ? (
<AiOutlineUp
className="cursor-pointer"
ref={ref}
onClick={() => setIsOpen(true)}
/>
) : (
<AiOutlineDown
className="cursor-pointer"
ref={ref}
onClick={() => setIsOpen(true)}
/>
)}
</div>
{isOpen && (
<div
className="bg-gradient-to-r from-blue-200 to-purple-500 w-full text-left rounded-b-md p-4 "
ref={ref}
>
<p className="font-bold text-gray-800 text-sm ">Lekcje w:</p>
<p className="text-gray-800 text-sm">PN: 8-12</p>
</div>
)}
</div>
);
};
export const CardSubject = memo(Card);
Custom hook with ref:
export default function useHandleOpen() {
const [isOpen, setIsOpen] = useState(false);
const ref = useRef(null);
const handleClickOutside = (event) => {
if (ref.current && !ref.current.contains(event.target)) {
setIsOpen(!isOpen);
}
};
useEffect(() => {
document.addEventListener("click", handleClickOutside, !isOpen);
return () => {
document.removeEventListener("click", handleClickOutside, !isOpen);
};
});
return { ref, isOpen, setIsOpen };
}
Edit: Tried change it this way, but this displays warning too.
export default function useHandleOpen(ref) {
const [isOpen, setIsOpen] = useState(false);
const handleClickOutside = (event) => {
if (ref.current && !ref.current.contains(event.target)) {
setIsOpen(!isOpen);
}
};
useEffect(() => {
document.addEventListener("click", handleClickOutside, !isOpen);
return () => {
document.removeEventListener("click", handleClickOutside, !isOpen);
};
});
return { ref, isOpen, setIsOpen };
}
And use hook like this:
const editRef = useRef(null);
const { ref, isOpen, setIsOpen } = useHandleOpen(editRef);
Ok i fixed it by removing ref from places where i use onClick method for changing the state

React useState - save variables to local storage

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 hooks but i couldnt figure it. Below is my code.
LocalStorage.js
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
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
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
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.
setUploadUrl(result.url);
id = new Date().getTime().toString();
const newBook = {
id: id,
bookName: bookName,
writerName: writerName,
pageNumber: pageNumber,
uploadUrl: uploadUrl
};
In here you are updating the uploadUrl to the newBook object. But the value of uploadUrl hold the previous record. Instead of setting from uploadUrl, set it from result.url.

Categories

Resources