You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+TypeScript中如何将子组件的数组对象传递给父组件?

解决React子组件向父组件传递新增书籍数据的问题

核心问题是React组件间的状态传递逻辑——子组件无法直接修改父组件状态,必须通过父组件传递回调函数的方式实现数据向上传递。以下是具体修改方案:

1. 修改父组件(Booklists)

  • 新增回调函数handleAddBook,用于接收子组件传来的新书籍数据,并更新父组件的books状态
  • 修复useEffect的依赖问题(原依赖books会导致无限请求接口,改为空数组仅在组件挂载时请求一次)
  • 将回调函数作为props传给子组件NewBookModal

修改后的父组件代码:

import { useState, useEffect } from "react";
import { IBook, NewBook } 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)
            })
    }

    // 处理子组件传来的新书籍
    const handleAddBook = (newBook: NewBook) => {
        // 转换类型:NewBook的image是可选,IBook是必填,这里给默认值(可根据需求调整)
        const bookToAdd: IBook = {
            ...newBook,
            image: newBook.image || "" // 也可设置默认占位图URL
        }
        // 将新书籍添加到现有列表
        setBooks(prevBooks => [...prevBooks, bookToAdd])
    }

    useEffect(() => {
        getData()
    }, []) // 改为空数组,仅组件挂载时请求一次

    return (
        <div>
            {/* 传递回调函数给子组件 */}
            <NewBookModal onAddBook={handleAddBook} />
            <BooklistItem book={books} />
        </div>
    )
}

export default Booklists;

2. 修改子组件(NewBookModal)

  • 移除子组件内部的bookData状态(无需自行存储,父组件已统一维护书籍列表)
  • 定义props类型,接收父组件传来的onAddBook回调函数
  • 在addNewBook函数中调用onAddBook,将新书籍数据传递给父组件

修改后的子组件代码:

import { ChangeEvent, useState } from "react";
import { NewBook } from './BookType'

// 定义子组件的props类型
interface NewBookModalProps {
    onAddBook: (book: NewBook) => void;
}

function NewBookModal({ onAddBook }: NewBookModalProps) {
    const [title, setTitle] = useState<string>("")
    const [url, setUrl] = useState<string>("")
    const [description, setDescription] = useState<string>("")
    const [image, setImage] = useState<string>("") // 可选:如果需要用户输入图片链接

    const changeValue = (event: ChangeEvent<HTMLInputElement>) => {
        const { name, value } = event.target;
        // 用switch优化多条件判断,更简洁
        switch(name) {
            case "title":
                setTitle(value);
                break;
            case "url":
                setUrl(value);
                break;
            case "description":
                setDescription(value);
                break;
            case "image":
                setImage(value);
                break;
            default:
                break;
        }
    }

    const addNewBook = () => {
        // 构造新书籍对象
        const newBook: NewBook = {
            title,
            url,
            description,
            image
        };
        // 调用父组件的回调函数,传递数据
        onAddBook(newBook);
        // 清空输入框
        setTitle("")
        setUrl("")
        setDescription("")
        setImage("")
    }

    return (
        // 模态框UI示例,可根据实际需求调整
        <div>
            <input type="text" name="title" value={title} onChange={changeValue} placeholder="书名" />
            <input type="text" name="url" value={url} onChange={changeValue} placeholder="书籍链接" />
            <input type="text" name="description" value={description} onChange={changeValue} placeholder="书籍描述" />
            <input type="text" name="image" value={image} onChange={changeValue} placeholder="图片链接(可选)" />
            <button onClick={addNewBook}>添加书籍</button>
        </div>
    )
}

export default NewBookModal;

关键改动说明

  • 父子组件通信:通过父组件传递回调函数onAddBook,子组件调用该函数实现数据向上传递,这是React单向数据流的标准实现方式
  • 状态统一管理:书籍列表状态由父组件集中维护,子组件仅负责收集用户输入并通知父组件更新,避免状态分散
  • 类型兼容处理:针对NewBook和IBook的类型差异,补充必填字段的默认值,确保数据能正确存入父组件状态
  • 性能优化:修复useEffect的依赖问题,避免无限重复请求接口

内容的提问来源于stack exchange,提问作者Utku ARSLAN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 22:48:19