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
相关产品推荐
相关产品推荐

