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

如何从动态输入框获取字符串值?解决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返回错误提示值未定义。


解决方案

错误原因

  1. 索引不匹配:array.map(index => ...)中的index如果不是连续的0-based索引(比如array是[1,2,3]这类自定义值),会导致myRef.current.children[index]获取到错误的DOM元素甚至不存在的元素,自然value就是undefined。
  2. 直接操作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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 16:35:14