skip to Main Content

I try to add new book details like title,descripton… I can set bookData with input values but i can’t pass from child to parent.
This is my child comp. and i can see array with console.log in bookData

import { ChangeEvent, useState } from "react";
import { NewBook } from './BookType'
function NewBookModal() {
    const [title, settitle] = useState<string>("")
    const [url, seturl] = useState<string>("")
    const [description, setdescription] = useState<string>("")
    const [bookData, setBookData] = useState<NewBook[]>([])

    const changeValue = (event: ChangeEvent<HTMLInputElement>) => {
        if (event.target.name === "title") {
            settitle(event.target.value)
        }
        if (event.target.name === "url") {
            seturl(event.target.value)
        }
        if (event.target.name === "description") {
            setdescription(event.target.value)
        }
    }
    const addNewBook = () => {
        debugger
        setBookData([
            ...bookData,
            { description: description, title: title, url: url, }
        ]);
        seturl("")
        settitle("")
        setdescription("")
return(...

these are interfaces

export interface IBook {
    url:string,
    description:string,
    title:string,
    image:string
}
export interface NewBook{
    url:string,
    description:string,
    title:string,
    image?:string,
}

and this is my parent comp.

import { IBook } from './BookType'
import BooklistItem from './BooklistItem'
import NewBookModal from './NewBook';
function Booklists() {
    const [books, setBooks] = useState<IBook[]>([]);
    const url = "https://localhost:7065/api/BookRecommendation"
    const getData = () => {
        fetch(url)
            .then(res => res.json())
            .then(res => {
                setBooks(res.data)
            })
    }
    useEffect(() => {
        getData()
    }, [books])
    return (
        <div>
            <NewBookModal/>
            <BooklistItem book={books} />
        </div>
    )

}

i did everythings that comes to my mind but didn’t work

2

Answers


  1. Pass setBooks from parent component

    <NewBookModal setBooks={setBooks} />
    

    In Child component while adding new book setBooks with previous state:

    const addNewBook = () => {
    setBooks((prevState) => {
      return [...prevState, { description, title, url }];
    });
    

    };

    Login or Signup to reply.
  2. In your parent componenet Booklists you can create a function that takes a NewBook as paramater and add it to books :

    const addNewBook(book : NewBook) => {
      setBooks([...books,book])
    }
    

    Then pass this function to <NewBookModal/> as props so you can use it from the child componenet to add a new book to the state of the parent one :

    <NewBookModal addbook={addNewBook}/>
    

    and from NewBookModal :

    function NewBookModal({addbook}) {
    //...
    addbook({ description: description, title: title, url: url})
    }
    

    But here the problem is that, in you parent component, you have declared your state this way :

    const [books, setBooks] = useState<IBook[]>([]);
    

    However it will recieve items of type newBook
    I don’t really see a reason for having this two types what I suggest is to have only one type book and use it everywhere:

    export interface Book{
        url:string,
        description:string,
        title:string,
        image?:string,
    }
    

    You can always check with :

    if(myBook.imgage) // here myBook is an instance of `Book`
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search