如何在ReactJS中使用Typescript将数组子对象传递给父组件

huangapple go评论76阅读模式
英文:

How pass object of array child to parent with Typescript in ReactJS

问题

以下是您要翻译的代码部分:

I try to add new book details like title, description... 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 an 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 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 &quot;react&quot;;
import { NewBook } from &#39;./BookType&#39;
function NewBookModal() {
    const [title, settitle] = useState&lt;string&gt;(&quot;&quot;)
    const [url, seturl] = useState&lt;string&gt;(&quot;&quot;)
    const [description, setdescription] = useState&lt;string&gt;(&quot;&quot;)
    const [bookData, setBookData] = useState&lt;NewBook[]&gt;([])

    const changeValue = (event: ChangeEvent&lt;HTMLInputElement&gt;) =&gt; {
        if (event.target.name === &quot;title&quot;) {
            settitle(event.target.value)
        }
        if (event.target.name === &quot;url&quot;) {
            seturl(event.target.value)
        }
        if (event.target.name === &quot;description&quot;) {
            setdescription(event.target.value)
        }
    }
    const addNewBook = () =&gt; {
        debugger
        setBookData([
            ...bookData,
            { description: description, title: title, url: url, }
        ]);
        seturl(&quot;&quot;)
        settitle(&quot;&quot;)
        setdescription(&quot;&quot;)
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 &#39;./BookType&#39;
import BooklistItem from &#39;./BooklistItem&#39;
import NewBookModal from &#39;./NewBook&#39;;
function Booklists() {
    const [books, setBooks] = useState&lt;IBook[]&gt;([]);
    const url = &quot;https://localhost:7065/api/BookRecommendation&quot;
    const getData = () =&gt; {
        fetch(url)
            .then(res =&gt; res.json())
            .then(res =&gt; {
                setBooks(res.data)
            })
    }
    useEffect(() =&gt; {
        getData()
    }, [books])
    return (
        &lt;div&gt;
            &lt;NewBookModal/&gt;
            &lt;BooklistItem book={books} /&gt;
        &lt;/div&gt;
    )

}

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

答案1

得分: 0

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 }];
});
};

英文:

Pass setBooks from parent component

&lt;NewBookModal setBooks={setBooks} /&gt;

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

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

};

答案2

得分: 0

在你的父组件 Booklists 中,你可以创建一个接受 NewBook 作为参数的函数,并将其添加到 books 中:

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

然后将这个函数传递给 <NewBookModal/> 作为 props,这样你可以从子组件中使用它来向父组件的状态中添加新书:

<NewBookModal addbook={addNewBook}/>

NewBookModal 中可以这样使用这个函数:

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

但问题在于,在你的父组件中,你以这种方式声明了状态:

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

然而,它将接收类型为 newBook 的项目。
我不太明白为什么要有这两种类型,我建议只使用一种类型 book 并在所有地方使用它:

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

你可以随时检查:

if (myBook.image) // 这里 myBook 是 `Book` 的一个实例
英文:

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) =&gt; {
  setBooks([...books,book])
}

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

&lt;NewBookModal addbook={addNewBook}/&gt;

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&lt;IBook[]&gt;([]);

However it will recieve items of type newBook <br> 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`

huangapple
  • 本文由 发表于 2023年2月24日 01:48:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75548514.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定