如何从动态输入框获取字符串值?解决Firestore存储undefined问题
问题:动态生成的日期输入框值存入Firestore时显示undefined
我通过用户输入的数量动态生成date类型的input标签,点击提交按钮时需将所有输入框的值存入数组并保存到Firestore数据库,但存储时提示输入值为undefined,怀疑获取的是对象而非字符串。
HTML/JSX代码
<div> <div id='dates' ref={myRef} className='fields_container'> { array.map(index => <input key={index} type="date"/> ) } </div> <div className="btn"> <Button variant="contained" size="large" onClick={handleClick} sx={ { fontSize: 25, color: "black", backgroundColor: "#d19c97", fontFamily: "'Caveat', cursive", boxShadow: "2px 2px 52px black", '&:hover': { backgroundColor: "black", color: "white", boxShadow: "2px 2px 52px black" } } } > Suivant </Button> </div> </div>
提交处理函数代码
const handleClick = async () => { // 初始化存储输入值的数组 let values = [] // 将输入值存入数组 array.map(index => values.push(myRef.current.children[index].value)) try { const clientRef = await doc(db, "SEANCES_COLLECTIONS", clientName) await setDoc(clientRef, {seances: values}, {merge: true}) console.log('réussie !') setLoading(false) } catch (error) { // 控制台打印输入值数组 console.log(values) // 控制台打印错误(提示所有值都是undefined) console.log(error) } }
控制台情况
控制台输出的values数组所有元素都是undefined,同时Firestore返回错误提示值未定义。
解决方案
错误原因
- 索引不匹配:
array.map(index => ...)中的index如果不是连续的0-based索引(比如array是[1,2,3]这类自定义值),会导致myRef.current.children[index]获取到错误的DOM元素甚至不存在的元素,自然value就是undefined。 - 直接操作DOM的风险:React中直接通过ref操作DOM不是最佳实践,容易出现组件渲染后DOM结构与array不同步的问题。
方案一:用React状态管理输入值(推荐)
通过React状态跟踪每个输入框的值,避免直接操作DOM,同时保证数据与UI同步:
import { useState, useEffect } from 'react'; // 假设用户输入的数量为count,初始化对应长度的日期状态数组 const [dates, setDates] = useState([]); useEffect(() => { // 当count变化时,重置dates数组为对应长度的空字符串 setDates(new Array(count).fill('')); }, [count]); // 渲染输入框时绑定状态和 onChange 事件 <div id='dates' className='fields_container'> {dates.map((date, index) => ( <input key={index} type="date" value={date} onChange={(e) => { // 更新对应索引的日期值 const updatedDates = [...dates]; updatedDates[index] = e.target.value; setDates(updatedDates); }} /> ))} </div> // 修改后的提交函数 const handleClick = async () => { try { const clientRef = doc(db, "SEANCES_COLLECTIONS", clientName); // 直接使用状态数组dates await setDoc(clientRef, { seances: dates }, { merge: true }); console.log('保存成功!'); setLoading(false); } catch (error) { console.log(dates); console.log(error); } };
方案二:修复DOM获取方式(临时解决)
如果不想修改状态管理逻辑,可直接遍历ref下的所有input元素,不依赖原array:
const handleClick = async () => { let values = []; // 遍历ref下的所有子元素,筛选出input标签并获取值 Array.from(myRef.current.children).forEach(child => { if (child.tagName === 'INPUT') { values.push(child.value); } }); try { const clientRef = await doc(db, "SEANCES_COLLECTIONS", clientName); await setDoc(clientRef, {seances: values}, {merge: true}); console.log('réussie !'); setLoading(false); } catch (error) { console.log(values); console.log(error); } }
内容的提问来源于stack exchange,提问作者fathi93
相关产品推荐
相关产品推荐

