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

React动态输入组件问题:单个输入框值无法存入数组

问题原因与解决方法

问题根源

当页面中只有一个name="score"的输入框时,ev.target.elements.score返回的是单个DOM元素,而非多个输入时的HTMLCollection集合。这时候用Array.from(inputs)会错误地将DOM对象的属性当成迭代项处理,导致无法正确获取输入值。另外,getPercent函数里还存在笔误——原本应该获取name="percent"的输入框,却写成了score,这会导致永远拿不到百分比输入框的值。

修复方案

修改getInput和getPercent函数,先把获取到的输入项统一转换成数组格式,不管是单个还是多个输入都能正确处理:

// GET INPUT VALUE
const getInput = (ev) => {
   ev.preventDefault();
   const inputs = ev.target.elements.score;
   // 统一转成数组:单个元素就包装成数组,集合则直接转数组
   const inputArray = Array.isArray(inputs) ? inputs : [inputs];
   const newScores = inputArray.map((input) => input.value);
   setValuescore(newScores);
};

// GET PERCENT VALUE
const getPercent = (ev) => {
   ev.preventDefault();
   const inputs = ev.target.elements.percent; // 修正笔误,从score改为percent
   const inputArray = Array.isArray(inputs) ? inputs : [inputs];
   const newPercents = inputArray.map((input) => input.value);
   setValuepercent(newPercents);
};

完整修改后的代码

import React, {useState} from 'react';
import './button.css';

function DynamicInput() {
   const [score, setScore] = useState([]);
   const [percent, setPercent] = useState([]);
   const [valuescore, setValuescore] = useState([]);
   const [valuepercent, setValuepercent] = useState([]);
   const LIMIT = 3;

   // ADD SCORE INPUT
   function handleScore() {
      if (score.length < LIMIT) {
         setScore([...score, <input key={score.length} type="text" placeholder={'SCORE'} name="score" />]);
      }
   }

   // ADD PERCENT INPUT
   function handlePercent() {
      if (percent.length < LIMIT) {
         setPercent([...percent, <input key={percent.length} type="text" placeholder={'PERCENT'} name="percent" />]);
      }
   }

   // REMOVE INPUT
   function handleRemove() {
      if (score.length > 0) {
         const newInputs = [...score];
         const newPercent = [...percent];
         newInputs.pop();
         newPercent.pop();
         setScore(newInputs);
         setPercent(newPercent);
      } else {
         alert('No puedes retirar mas inputs');
      }
   }

   // GET INPUT VALUE
   const getInput = (ev) => {
      ev.preventDefault();
      const inputs = ev.target.elements.score;
      const inputArray = Array.isArray(inputs) ? inputs : [inputs];
      const newScores = inputArray.map((input) => input.value);
      setValuescore(newScores);
   };

   // GET PERCENT VALUE
   const getPercent = (ev) => {
      ev.preventDefault();
      const inputs = ev.target.elements.percent;
      const inputArray = Array.isArray(inputs) ? inputs : [inputs];
      const newPercents = inputArray.map((input) => input.value);
      setValuepercent(newPercents);
   };


   return (
      <div>
         <div className="Binputs">
            <form id="valueScore" className="content" onSubmit={getInput}>
               {score.map((input) => input)}
            </form>
            <form id="valuePercent" className="content" onSubmit={getPercent}>
               {percent.map((input) => input)}
            </form>
         </div>
         <button
            onClick={() => {
               handleScore();
               // handlePercent();
            }}
         >
            Agregar
         </button>
         <button onClick={handleRemove}>Retirar</button>
         <button type="submit" form="valueScore">
            Calcular
         </button>
      </div>
   );
}

export default DynamicInput;

额外优化建议

  • 不要直接把React元素存在state里,更好的做法是存输入框的数量,渲染时根据数量生成输入框,代码更易维护:
    // 用数量代替存元素数组
    const [scoreCount, setScoreCount] = useState(0);
    // 渲染输入框
    {Array.from({length: scoreCount}, (_, idx) => (
       <input key={idx} type="text" placeholder="SCORE" name="score" />
    ))}
    
  • 可以将两个表单合并,统一处理提交逻辑,让结构更紧凑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 02:32:36