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

React输入框赋值报错Uncaught TypeError: data[index] is undefined求解

问题解决:非顺序输入输入框触发TypeError错误

问题原因

你当前代码的核心问题是用allPlants的循环索引去访问plantsFill数组,但plantsFill的元素是通过勾选复选框才添加的,它的长度、元素索引和allPlants完全不对应。比如先勾选第3个条目,plantsFill里只有1个元素(索引0),但输入框用的是index=2,去访问data[2]自然会出现data[index] is undefined的错误。

解决方案

放弃依赖allPlants的索引,改用plant_id来定位plantsFill中的元素;同时使用React的函数式状态更新,避免闭包导致的旧状态问题。

修改后的完整代码

const [allPlants, setAllPlants] = useState([]);
const [plantsFill, setPlantsFill] = useState([]);

{allPlants.map((t) => {
  // 判断当前条目是否被勾选
  const isChecked = plantsFill.some(item => item.plant_id === t.plant_id);
  // 获取当前条目的已输入值
  const currentEffectiveness = plantsFill.find(item => item.plant_id === t.plant_id)?.effectiveness || '';

  return (
    <div className="form-row mb-2" key={t.plant_id}> {/* 用唯一的plant_id作为key,避免索引混乱 */}
      <div className="col-md-2">
        <div className="form-check">
          <input
            type="checkbox"
            className="form-check-input"
            checked={isChecked} {/* 受控组件,同步勾选状态 */}
            onChange={(e) => {
              setPlantsFill(prevState => {
                if (e.target.checked) {
                  // 避免重复添加相同plant_id的条目
                  if (!prevState.some(item => item.plant_id === t.plant_id)) {
                    return [...prevState, { plant_id: t.plant_id, effectiveness: '' }];
                  }
                  return prevState;
                } else {
                  // 移除对应plant_id的条目
                  return prevState.filter(pItem => pItem.plant_id !== t.plant_id);
                }
              });
            }}
          />
          <label className="form-check-label">{t.title}</label>
        </div>
      </div>

      {/* 仅勾选时显示输入框 */}
      {isChecked && (
        <div className="col-md-1">
          <input
            type="text"
            className="form-control"
            value={currentEffectiveness} {/* 受控组件,同步输入值 */}
            onChange={(e) => {
              setPlantsFill(prevState => {
                // 通过plant_id找到对应条目并更新effectiveness
                return prevState.map(item => {
                  if (item.plant_id === t.plant_id) {
                    return { ...item, effectiveness: e.target.value };
                  }
                  return item;
                });
              });
            }}
          />
        </div>
      )}
    </div>
  );
})}

关键修改点说明

  1. 用plant_id作为组件key:替代不稳定的循环索引,避免列表重渲染时的组件识别错误。
  2. 函数式状态更新:setPlantsFill(prevState => ...)确保每次操作都基于最新的状态,解决连续操作时的闭包问题。
  3. 基于plant_id定位元素:修改输入值时通过plant_id匹配plantsFill中的条目,彻底解决索引不匹配的错误。
  4. 受控组件优化:复选框和输入框都设为受控组件,同步状态与视图;输入框仅在勾选时显示,避免无效操作。
  5. 初始化默认值:添加条目时默认带上effectiveness: '',避免后续添加属性时的潜在问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 10:10:49