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

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

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

问题

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

  1. 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.
  2. This is my child comp. and I can see an array with console.log in bookData
  1. import { ChangeEvent, useState } from "react";
  2. import { NewBook } from './BookType';
  3. function NewBookModal() {
  4. const [title, settitle] = useState<string>("");
  5. const [url, seturl] = useState<string>("");
  6. const [description, setdescription] = useState<string>("");
  7. const [bookData, setBookData] = useState<NewBook[]>([]);
  8. const changeValue = (event: ChangeEvent<HTMLInputElement>) => {
  9. if (event.target.name === "title") {
  10. settitle(event.target.value);
  11. }
  12. if (event.target.name === "url") {
  13. seturl(event.target.value);
  14. }
  15. if (event.target.name === "description") {
  16. setdescription(event.target.value);
  17. }
  18. }
  19. const addNewBook = () => {
  20. debugger
  21. setBookData([
  22. ...bookData,
  23. { description: description, title: title, url: url, }
  24. ]);
  25. seturl("")
  26. settitle("")
  27. setdescription("")
  28. return...
  1. these are interfaces
  1. export interface IBook {
  2. url:string,
  3. description:string,
  4. title:string,
  5. image:string
  6. }
  7. export interface NewBook{
  8. url:string,
  9. description:string,
  10. title:string,
  11. image?:string,
  12. }
  1. and this is my parent comp.
  1. import { IBook } from './BookType';
  2. import BooklistItem from './BooklistItem';
  3. import NewBookModal from './NewBook';
  4. function Booklists() {
  5. const [books, setBooks] = useState<IBook[]>([]);
  6. const url = "https://localhost:7065/api/BookRecommendation";
  7. const getData = () => {
  8. fetch(url)
  9. .then(res => res.json())
  10. .then(res => {
  11. setBooks(res.data);
  12. })
  13. }
  14. useEffect(() => {
  15. getData();
  16. }, [books]);
  17. return (
  18. <div>
  19. <NewBookModal/>
  20. <BooklistItem book={books} />
  21. </div>
  22. )
  23. }

希望这有助于您的代码理解和问题解决。如果您有任何其他问题,请随时提出。

英文:

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

  1. import { ChangeEvent, useState } from &quot;react&quot;;
  2. import { NewBook } from &#39;./BookType&#39;
  3. function NewBookModal() {
  4. const [title, settitle] = useState&lt;string&gt;(&quot;&quot;)
  5. const [url, seturl] = useState&lt;string&gt;(&quot;&quot;)
  6. const [description, setdescription] = useState&lt;string&gt;(&quot;&quot;)
  7. const [bookData, setBookData] = useState&lt;NewBook[]&gt;([])
  8. const changeValue = (event: ChangeEvent&lt;HTMLInputElement&gt;) =&gt; {
  9. if (event.target.name === &quot;title&quot;) {
  10. settitle(event.target.value)
  11. }
  12. if (event.target.name === &quot;url&quot;) {
  13. seturl(event.target.value)
  14. }
  15. if (event.target.name === &quot;description&quot;) {
  16. setdescription(event.target.value)
  17. }
  18. }
  19. const addNewBook = () =&gt; {
  20. debugger
  21. setBookData([
  22. ...bookData,
  23. { description: description, title: title, url: url, }
  24. ]);
  25. seturl(&quot;&quot;)
  26. settitle(&quot;&quot;)
  27. setdescription(&quot;&quot;)
  28. return(...

these are interfaces

  1. export interface IBook {
  2. url:string,
  3. description:string,
  4. title:string,
  5. image:string
  6. }
  7. export interface NewBook{
  8. url:string,
  9. description:string,
  10. title:string,
  11. image?:string,
  12. }

and this is my parent comp.

  1. import { IBook } from &#39;./BookType&#39;
  2. import BooklistItem from &#39;./BooklistItem&#39;
  3. import NewBookModal from &#39;./NewBook&#39;;
  4. function Booklists() {
  5. const [books, setBooks] = useState&lt;IBook[]&gt;([]);
  6. const url = &quot;https://localhost:7065/api/BookRecommendation&quot;
  7. const getData = () =&gt; {
  8. fetch(url)
  9. .then(res =&gt; res.json())
  10. .then(res =&gt; {
  11. setBooks(res.data)
  12. })
  13. }
  14. useEffect(() =&gt; {
  15. getData()
  16. }, [books])
  17. return (
  18. &lt;div&gt;
  19. &lt;NewBookModal/&gt;
  20. &lt;BooklistItem book={books} /&gt;
  21. &lt;/div&gt;
  22. )
  23. }

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

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

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

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

};

答案2

得分: 0

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

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

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

  1. <NewBookModal addbook={addNewBook}/>

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

  1. function NewBookModal({ addbook }) {
  2. //...
  3. addbook({ description: description, title: title, url: url})
  4. }

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

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

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

  1. export interface Book {
  2. url: string,
  3. description: string,
  4. title: string,
  5. image?: string,
  6. }

你可以随时检查:

  1. 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 :

  1. const addNewBook(book : NewBook) =&gt; {
  2. setBooks([...books,book])
  3. }

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 :

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

and from NewBookModal :

  1. function NewBookModal({addbook}) {
  2. //...
  3. addbook({ description: description, title: title, url: url})
  4. }

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

  1. 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:

  1. export interface Book{
  2. url:string,
  3. description:string,
  4. title:string,
  5. image?:string,
  6. }

You can always check with :

  1. 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:

确定