React JS中如何获取动态生成输入框的独立数据?
解决动态生成学期输入框的独立状态存储问题
核心问题分析
你当前的状态结构里,credit和sgpa是单个值,所有动态输入框都绑定这两个值,自然会出现共享状态的问题。要实现每个学期数据独立,需要把状态改成数组结构,每个数组元素对应一个学期的credit和sgpa。
具体修改方案
1. 调整状态结构
把原来的单个credit、sgpa替换为数组semesters,每个元素是存储对应学期数据的对象:
const [state, setState] = useState({ semester: "", semesters: [] // 每个元素格式:{ credit: '', sgpa: '' } });
2. 修改学期提交逻辑
用户输入学期数后,初始化对应数量的空学期数据对象到数组中,同时可以去掉原来单独维护的noOfSem状态,直接用semesters.length判断渲染:
const handleClick = () => { const semesterCount = parseInt(state.semester, 10); if (isNaN(semesterCount) || semesterCount <= 0) return; // 生成对应数量的空学期数据 const initialSemesters = Array.from({ length: semesterCount }, () => ({ credit: "", sgpa: "" })); setState(prev => ({ ...prev, semesters: initialSemesters })); };
3. 更新输入框 onChange 逻辑
给每个动态输入框添加data-index属性标识学期索引,区分总学期数输入和单个学期的字段输入:
const handleChange = (e) => { const { name, value } = e.target; // 处理总学期数输入 if (name === "semester") { setState(prev => ({ ...prev, semester: value })); return; } // 处理单个学期的学分/绩点输入 const index = parseInt(e.target.dataset.index, 10); setState(prev => { const updatedSemesters = [...prev.semesters]; // 更新对应学期的指定字段 updatedSemesters[index] = { ...updatedSemesters[index], [name]: value }; return { ...prev, semesters: updatedSemesters }; }); };
4. 调整渲染逻辑
动态生成输入框时,绑定对应学期的value和data-index属性:
{state.semesters.length > 0 && ( <div className="col form2"> {state.semesters.map((sem, index) => ( <div key={index} className="col-md seminpt"> <label>Semester {index + 1}</label> <input type="Number" name="credit" data-index={index} value={sem.credit} onChange={handleChange} placeholder="Total Credit" /> <input type="Number" name="sgpa" data-index={index} value={sem.sgpa} onChange={handleChange} placeholder={`SGPA sem${index + 1}`} /> </div> ))} <button type="button" className="btn btn-success btn3334" onClick={handleCgpaSubmit} > Submit </button> </div> )}
5. 重置与提交逻辑更新
- 重置按钮直接清空
semesters数组和semester值:
const emptySemester = () => { setState({ semester: "", semesters: [] }); };
- 提交时直接获取所有学期的独立数据:
const handleCgpaSubmit = () => { console.log("所有学期数据:", state.semesters); // 可选:添加CGPA计算逻辑 const totalPoints = state.semesters.reduce((sum, sem) => { const credit = parseFloat(sem.credit); const sgpa = parseFloat(sem.sgpa); return sum + (credit * sgpa || 0); }, 0); const totalCredits = state.semesters.reduce((sum, sem) => { return sum + (parseFloat(sem.credit) || 0); }, 0); const cgpa = totalCredits > 0 ? (totalPoints / totalCredits).toFixed(2) : 0; console.log("计算出的CGPA:", cgpa); };
修改后的完整代码
import React, { useState } from "react"; import cal from "./image/bgimg.jpg"; function Home() { const [state, setState] = useState({ semester: "", semesters: [] }); const handleChange = (e) => { const { name, value } = e.target; if (name === "semester") { setState(prev => ({ ...prev, semester: value })); return; } const index = parseInt(e.target.dataset.index, 10); setState(prev => { const updatedSemesters = [...prev.semesters]; updatedSemesters[index] = { ...updatedSemesters[index], [name]: value }; return { ...prev, semesters: updatedSemesters }; }); }; const handleClick = () => { const semesterCount = parseInt(state.semester, 10); if (isNaN(semesterCount) || semesterCount <= 0) return; const initialSemesters = Array.from({ length: semesterCount }, () => ({ credit: "", sgpa: "" })); setState(prev => ({ ...prev, semesters: initialSemesters })); }; const emptySemester = () => { setState({ semester: "", semesters: [] }); }; const handleCgpaSubmit = () => { console.log("所有学期数据:", state.semesters); const totalPoints = state.semesters.reduce((sum, sem) => { const credit = parseFloat(sem.credit); const sgpa = parseFloat(sem.sgpa); return sum + (credit * sgpa || 0); }, 0); const totalCredits = state.semesters.reduce((sum, sem) => { return sum + (parseFloat(sem.credit) || 0); }, 0); const cgpa = totalCredits > 0 ? (totalPoints / totalCredits).toFixed(2) : 0; console.log("计算出的CGPA:", cgpa); }; return ( <div className="container"> <div className="row"> <div className="col-md-6"> <img src={cal} alt="Calculator background" className="imgcal img-fluid" /> </div> <div className="col-md-6"> <div className="col-md"> <div className="form1"> <div className="col-md formmain"> <input type="number" value={state.semester} name="semester" onChange={handleChange} placeholder="Enter Total Semester" min="1" /> {state.semesters.length === 0 ? ( <button type="button" className="btn btn-success btn333" onClick={handleClick} > Submit </button> ) : ( <button type="button" className="btn btn-success btn333" onClick={emptySemester} > Reset Semester </button> )} </div> {state.semesters.length > 0 && ( <div className="col form2"> {state.semesters.map((sem, index) => ( <div key={index} className="col-md seminpt"> <label>Semester {index + 1}</label> <input type="Number" name="credit" data-index={index} value={sem.credit} onChange={handleChange} placeholder="Total Credit" min="0" /> <input type="Number" name="sgpa" data-index={index} value={sem.sgpa} onChange={handleChange} placeholder={`SGPA sem${index + 1}`} min="0" max="10" /> </div> ))} <button type="button" className="btn btn-success btn3334" onClick={handleCgpaSubmit} > Submit </button> </div> )} </div> </div> </div> </div> </div> ); } export default Home;
内容的提问来源于stack exchange,提问作者demi
相关产品推荐
相关产品推荐

