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

React函数组件:子组件用户输入传递至父组件问题求助

问题描述

我正在开发一款发票生成器,用户可添加商品名称、价格及数量。需要将子函数组件<TableItems.js>中的用户输入状态传递到父函数组件<TableSheet.js>,以便将数据存入Firestore数据库,但目前无法实现子组件到父组件的输入值传递,附上组件代码寻求帮助:

子组件代码(TableItems.js)

import React, {useState, useEffect} from 'react'

function TableItems({index, tableItem }) {
    const [price, setPrice] = useState(0);
    const [qty, setQty] = useState(0);
    const [total, setTotal] = useState([]);

useEffect(() => {
    //arithmetically add price and qty values
    const x = Number(price) * Number(qty)
    setTotal(x)
  return () => {
      //clean up function will be here
  };
  }, [price, qty, total ]);

return (
    <>
        <tr>
           <td><input type='text' required/></td>
            <td><input type='number' value={price} onChange={(e) => setPrice(e.target.value)}/></td>
            <td><input type='number' value={qty} onChange={(e) => setQty(e.target.value)}/></td>
            <td>{total}</td>
        </tr>
    </>
)
}

export default TableItems

父组件代码(TableSheet.js)

import React, { useState } from 'react'
 import TableItems from './TableItems'

 function TableSheet() {
   const [tableItem, setTableItem] = useState([1]);

  //adding a new table cell (table row)
   const addCell = () => {
      setTableItem((t) => [...t, t + 1])
   }

 return (
  <div>
  <table>
      <thead>
        <th>Item Description</th>
        <th>Price</th>
        <th>Qty.</th>
        <th>Total</th>
      </thead>
        {
          tableItem.map((tableItem, index, setItem) => {
            return <TableItems key={index} tableItem={tableItem} setItem={setItem} addCell={addCell}/>
          })
        }
    </table>
    <button onClick={addCell}>+</button>
</div>
)
}

export default TableSheet
解决方案

核心思路是将状态提升到父组件,让父组件统一管理所有商品项的数据,子组件仅负责渲染和触发更新回调。

1. 重构父组件状态

把原有的tableItem数组改为存储商品对象的结构,每个对象包含description、price、qty、total字段:

function TableSheet() {
  // 初始化商品列表,每个商品包含完整字段
  const [items, setItems] = useState([{ description: '', price: 0, qty: 0, total: 0 }]);

  // 添加新商品行
  const addCell = () => {
    setItems(prev => [...prev, { description: '', price: 0, qty: 0, total: 0 }]);
  };

2. 父组件实现商品更新回调

创建一个函数,接收商品索引、修改字段和对应值,更新指定商品数据并自动计算总价:

// 更新单个商品信息
  const updateItem = (index, field, value) => {
    setItems(prevItems => {
      const newItems = [...prevItems];
      // 更新目标字段
      newItems[index][field] = value;
      // 价格或数量变化时自动计算总价
      if (field === 'price' || field === 'qty') {
        newItems[index].total = Number(newItems[index].price) * Number(newItems[index].qty);
      }
      return newItems;
    });
  };

3. 修改子组件为受控组件

子组件不再维护自身状态,所有数据通过props接收,输入变化时调用父组件的更新函数:

import React from 'react'

function TableItems({ index, item, updateItem }) {
  return (
    <tr>
      <td>
        <input
          type='text'
          required
          value={item.description}
          onChange={(e) => updateItem(index, 'description', e.target.value)}
        />
      </td>
      <td>
        <input
          type='number'
          value={item.price}
          onChange={(e) => updateItem(index, 'price', e.target.value)}
        />
      </td>
      <td>
        <input
          type='number'
          value={item.qty}
          onChange={(e) => updateItem(index, 'qty', e.target.value)}
        />
      </td>
      <td>{item.total}</td>
    </tr>
  )
}

export default TableItems

4. 父组件传递正确的props

修改map循环,将商品数据、索引和更新函数传递给子组件:

return (
  <div>
    <table>
      <thead>
        <th>Item Description</th>
        <th>Price</th>
        <th>Qty.</th>
        <th>Total</th>
      </thead>
      <tbody>
        {items.map((item, index) => (
          <TableItems
            key={index}
            index={index}
            item={item}
            updateItem={updateItem}
          />
        ))}
      </tbody>
    </table>
    <button onClick={addCell}>+</button>
    {/* 可直接使用items数组提交到Firestore */}
    <button onClick={() => console.log('提交数据:', items)}>保存发票</button>
  </div>
)

关键说明

  • 状态提升是React父子组件传值的标准方案,确保数据统一由父组件管理,避免状态分散。
  • 总价计算逻辑放在父组件,保证数据一致性,无需子组件重复计算。
  • 父组件的items数组包含所有用户输入的商品数据,直接调用Firestore API即可完成数据存储。

内容的提问来源于stack exchange,提问作者Paul Simon Emechebe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 07:16:28