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

React中引用map渲染的输入框的最优方案是什么?

React中获取循环渲染输入框值的高效方案

核心思路:用受控组件替代DOM查询

在React里处理循环生成的输入框,别用document.getElementById——这会绕开React的状态管理逻辑,容易引发视图与数据不一致的问题。最靠谱高效的方案是用受控组件绑定状态,比折腾useRef简单得多,也更符合React的设计理念。

具体实现步骤

  1. 初始化状态存储输入值
    用一个对象保存所有输入框的值,键用每个练习的唯一标识(比如结合分组名和练习名,避免同名称练习冲突):
import { Fragment, useContext, useState } from "react";
import { RoutineContext } from "../../context/CurrentRoutineContext";

export default function Card() {
  const { data: session, status } = useSession();
  const { currentRoutine } = useContext(RoutineContext);
  // 初始化存储输入值的状态
  const [inputValues, setInputValues] = useState({});
  1. 给输入框绑定状态与变更事件
    循环渲染时,给每个输入框绑定value属性和onChange事件,实时更新对应状态:
return (
    <>
      {currentRoutine.sections.map((section) => (
          <div key={section.name} className="w-full rounded-md sm:max-w-md sm:shadow-lg">
            {/* 头部 */}
            <div className="px-4 py-5 border-b border-gray-200 shadow-md bg-gravel-400 sm:px-6">
              <h3 className="text-xl font-medium leading-6 text-center text-slate-100">
                {section.name}
              </h3>
            </div>
            {/* 主体 */}
            <div className="p-3">
              {section.exercises.map((exercise) => {
                // 生成唯一键,避免同名称练习的输入值冲突
                const inputKey = `${section.name}-${exercise.name}`;
                return (
                  <div key={exercise.name} className="px-2 py-1.5">
                    <span className="block font-semibold text-gravel-700">{exercise.name}</span>
                    <table className="min-w-full">
                      <thead>
                        <tr key={exercise.name}>
                          // 表格表头....
                        </tr>
                      </thead>
                      <tbody className="divide-y divide-gray-200">
                        <tr key={exercise.name} className="w-full py-1">
                          <td className="px-2 text-sm text-gray-500 whitespace-nowrap">
                            <input
                              type="number"
                              className="w-12 pl-1 text-base rounded-sm bg-gravel-100"
                              value={inputValues[inputKey] || ""}
                              onChange={(e) => {
                                setInputValues(prev => ({
                                  ...prev,
                                  [inputKey]: e.target.value
                                }));
                              }}
                            />
                          </td>
                          <td>
                            <button
                              disabled={false}
                              onClick={() => {
                                // 点击时可直接读取对应输入值
                                console.log(inputValues[inputKey]);
                              }}
                              type="button"
                            >
                              <CheckIcon className="w-5 h-5 p-1 text-center text-stone-800" />
                            </button>
                          </td>
                        </tr>
                      </tbody>
                    </table>
                  </div>
                );
              })}
            </div>
          </div>
      ))}
    </>
  );
}
  1. 批量获取输入值
    当需要读取所有输入框的值时,直接使用inputValues状态即可,比如提交表单时:
// 示例:添加提交按钮获取所有值
<button onClick={() => console.log("所有输入值:", inputValues)}>提交</button>

实用技巧补充

  • 更可靠的唯一标识:如果练习数据里有id字段,优先用id作为状态的键,比名称更不容易重复;
  • 默认值初始化:如果需要给输入框设置默认值,可以在组件挂载时,根据currentRoutine的数据初始化inputValues;
  • 特殊场景用Ref:如果确实需要操作DOM(比如自动聚焦),可以用useRef创建一个Map存储每个输入框的ref:
    const inputRefs = useRef(new Map());
    
    // 循环时给输入框赋值ref
    <input
      ref={(el) => el && inputRefs.current.set(inputKey, el)}
      // ...其他属性
    />
    
    // 使用时:比如聚焦指定输入框
    inputRefs.current.get(inputKey)?.focus();
    

内容的提问来源于stack exchange,提问作者Furkan Öz Türk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 06:35:17