如何获取多次渲染的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;
关键说明
- 数据与视图分离:父组件只管理数据,视图(Inputbox)根据数据渲染,这是React的核心思想,也方便后续对数据进行计算、修改等操作。
- 唯一key:用自增ID作为key,比
Math.random()更可靠,避免React渲染时出现异常。 - 求和逻辑:通过
filter筛选选中项,再用reduce计算总和,简单高效。 - 状态提升:把复选框的选中状态提升到父组件管理,这样能统一控制全选/全不选,也方便基于选中状态计算总和。
内容的提问来源于stack exchange,提问作者Maksudul Haque
相关产品推荐
相关产品推荐

