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

如何获取多次渲染的Inputbox组件传入的随机props值并求和

解决思路与代码修改

你的核心问题在于把JSX组件直接存在了state里,导致无法直接获取每个Inputbox的num值来计算总和。正确的做法是在父组件管理数据(随机数、选中状态),再根据数据渲染组件,这样就能轻松对数据进行求和操作。

步骤1:重构父组件的状态管理

把原来存JSX的components改成存数据数组,每个数据项包含唯一ID、随机数和选中状态,同时新增状态管理所有复选框的选中情况:

// app.jsx
import { useState, useRef } from "react";
import styles from "./css/app.module.css";
import Inputbox from "./Inputbox";

// 生成唯一ID(简单实现,也可以用uuid库)
let idCounter = 0;
const generateId = () => {
  return idCounter++;
};

function App() {
  // 存储每个输入框的数据:id、随机num、选中状态
  const [boxData, setBoxData] = useState([]);
  const boxCount = useRef(null);

  const handleKeyDown = (event) => {
    if (event.key === "Enter") {
      addComponent();
    }
  };

  function addComponent() {
    const count = parseInt(boxCount.current.value);
    if (isNaN(count) || count <= 0) return;
    
    // 批量生成数据项,而不是JSX
    const newBoxes = Array.from({ length: count }, () => ({
      id: generateId(),
      num: Math.random(),
      checked: true
    }));
    setBoxData(prev => [...prev, ...newBoxes]);
  }

  // 全选/全不选逻辑
  function checkAll() {
    setBoxData(prev => prev.map(item => ({
      ...item,
      checked: !prev.every(i => i.checked)
    })));
  }

  // 单个复选框状态变化回调
  const handleCheckChange = (id) => {
    setBoxData(prev => prev.map(item => 
      item.id === id ? { ...item, checked: !item.checked } : item
    ));
  };

  // 计算选中项的随机数总和
  const calculateTotal = () => {
    return boxData
      .filter(item => item.checked)
      .reduce((sum, item) => sum + item.num, 0)
      .toFixed(4); // 保留4位小数,避免精度问题
  };

  return (
    <div className={styles.container}>
      <input
        type="text"
        ref={boxCount}
        onKeyDown={handleKeyDown}
        placeholder="Enter number of box"
      />
      <button onClick={addComponent}>Add TextBox</button>
      <button onClick={checkAll}>Check all</button>
      {/* 显示总和 */}
      <div>选中项随机数总和:{calculateTotal()}</div>
      <div className={styles.componentList}>
        {/* 根据数据渲染Inputbox */}
        {boxData.map((item) => (
          <div key={item.id}>
            <Inputbox 
              num={item.num} 
              checked={item.checked}
              onCheckChange={() => handleCheckChange(item.id)}
            />
          </div>
        ))}
      </div>
    </div>
  );
}

export default App;

步骤2:修改Inputbox组件

去掉组件内部的checked状态,改为从props接收状态和回调,同时可以显示当前项的随机数:

// Inputbox.jsx
import styles from "./css/inputbox.module.css";
import { useRef } from "react";

const Inputbox = ({ num, checked, onCheckChange }) => {
  const inputVal = useRef(null);

  return (
    <div className={styles.container}>
      <input 
        type="checkbox" 
        checked={checked}
        onChange={onCheckChange} 
      />
      <input type="text" ref={inputVal} placeholder="Enter numbers" />
      {/* 显示当前项的随机数 */}
      <span>随机数:{num.toFixed(4)}</span>
    </div>
  );
};

export default Inputbox;

关键说明

  1. 数据与视图分离:父组件只管理数据,视图(Inputbox)根据数据渲染,这是React的核心思想,也方便后续对数据进行计算、修改等操作。
  2. 唯一key:用自增ID作为key,比Math.random()更可靠,避免React渲染时出现异常。
  3. 求和逻辑:通过filter筛选选中项,再用reduce计算总和,简单高效。
  4. 状态提升:把复选框的选中状态提升到父组件管理,这样能统一控制全选/全不选,也方便基于选中状态计算总和。

内容的提问来源于stack exchange,提问作者Maksudul Haque

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 16:50:25