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

React:无需useCallback,如何用单个useRef正确获取多输入组件的值?

问题分析

你遇到的核心问题是:单个useRef被循环渲染的所有Input组件复用,最终ref.current只会指向最后一个渲染的输入框。

在MenuItem组件中,你只创建了一个amountInputRef,然后在map循环里把这个ref绑定到每一个Input上。React在渲染时,每次循环都会覆盖这个ref的current属性,最后自然只会保留最后一个输入框的引用,所以无论点击哪个商品的"Add"按钮,获取到的都是最后一个输入框的值。

修复方案(无需多Ref,贴近原项目写法)

原项目没有使用多Ref,大概率是通过表单自身的DOM元素引用来获取输入值,这是更符合React表单处理逻辑的方式,具体修改如下:

1. 移除无用的useRef

删除MenuItem.js中useRef的导入和定义:

// 删掉这行
import { useRef } from "react";
// 删掉这行
const amountInputRef = useRef();

2. 给输入框添加name属性

在map循环的Input组件中,给input配置对象添加name和可选的defaultValue:

<Input
  input={{
    id: e.id,
    type: "number",
    min: "0",
    max: "5",
    name: "amount", // 新增name属性,用于表单取值
    defaultValue: 1 // 可选:设置默认数量为1
  }}
/>

3. 通过表单元素获取对应输入值

修改submitHandler,利用当前提交的表单(e.target就是当前的<form>元素),通过name属性定位到对应的输入框:

const submitHandler = (e) => {
  e.preventDefault();
  const mealId = e.target.id;
  // 通过表单的name属性获取当前商品的数量值
  const amount = e.target.amount.value;
  console.log(mealId, amount);
};

4. 修复key的不合理用法

把key={Math.random()}改成key={e.id},因为Math.random()会导致每次渲染生成新的key,破坏React的diff算法,影响性能:

<form id={e.id} key={e.id} onSubmit={submitHandler}>
为什么这个方案有效?

每个商品对应的<form>都是独立的DOM元素,提交时e.target指向当前触发提交的表单,通过e.target.amount可以精准获取当前表单内的输入框值,完全不需要依赖useRef,避免了单Ref被复用的问题,同时也和原项目的实现逻辑一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 19:23:15