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

如何用React-Redux处理map渲染的多输入框并解决NaN问题?

解决React表格总价NaN问题并初始化数量输入框为0

问题根源

你遇到的NaN问题核心来自两个点:

  • 初始qty是空对象,访问未定义的属性返回undefined,和单价相乘直接得到NaN
  • 数字输入框的value默认是字符串类型,若不转换直接参与计算,可能引发类型异常

具体修复方案

1. 初始化所有产品的数量为0

当Redux中的产品列表加载完成后,为每个产品生成初始数量0,确保qty对象包含所有产品的键值对:

const [qty, setQty] = useState({})

useEffect(() => {
  dispatch(fetchList())
}, [dispatch])

// 新增:监听list变化,初始化数量
useEffect(() => {
  if (list.length) {
    const initialQty = list.reduce((acc, item) => {
      acc[item.name] = 0
      return acc
    }, {})
    setQty(initialQty)
  }
}, [list])

2. 转换输入值为数字类型

输入框返回的value是字符串,必须转成数字后再存入状态,避免字符串与数字相乘的问题:

const handleChange = (e) => {
  e.preventDefault()
  const { name, value } = e.target;
  // 把输入值转为数字,非数字内容默认设为0
  const numValue = isNaN(Number(value)) ? 0 : Number(value)
  setQty({
    ...qty,
    [name]: numValue 
  });
}

3. 渲染时添加兜底默认值

在计算总价和渲染输入框时,添加?? 0兜底,防止列表未加载完成或状态异常时出现undefined:

// 表格中的总价列
<td>{item.price * (qty[item.name] ?? 0)}</td>

// 输入框的value属性
<FormInput
  type="number"
  name={item.name}
  handleChange={handleChange}
  value={qty[item.name] ?? 0} 
/>

// 计算总金额时的兜底
let sum = 0
list.forEach((item) => {
  sum += item.price * (qty[item.name] ?? 0)
})

修改后的完整代码

import FormInput from './Components/FormInput';
import { useEffect, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { fetchList } from './Components/Store/action';

function App() {
  const { list } = useSelector((state) => state.list)
  const dispatch = useDispatch()
  const [qty, setQty] = useState({})
 
  const handleChange = (e) => {
    e.preventDefault()
    const { name, value } = e.target;
    const numValue = isNaN(Number(value)) ? 0 : Number(value)
    setQty({
      ...qty,
      [name]: numValue 
    });
  }

  useEffect(() => {
    dispatch(fetchList())
  }, [dispatch])

  useEffect(() => {
    if (list.length) {
      const initialQty = list.reduce((acc, item) => {
        acc[item.name] = 0
        return acc
      }, {})
      setQty(initialQty)
    }
  }, [list])

  let sum = 0
  list.forEach((item) => {
    sum += item.price * (qty[item.name] ?? 0)
  })

  const submitHandler = (e) => {
    e.preventDefault()
  }

  return (
    <div >
      <form onSubmit={submitHandler}>
        <table>
          <thead>
            <tr>
              <th>S.no</th>
              <th>Name</th>
              <th>Unit</th>
              <th>price</th>
              <th>Quantity</th>
              <th>total</th>
            </tr>
          </thead>
          <tbody>
            {list.map((item) => (
              <tr key={item.id}>
                <td>{item.id}</td>
                <td>{item.name}</td>
                <td>{item.unit}</td>
                <td>{item.price}</td>
                <td>
                  <FormInput
                    type="number"
                    name={item.name}
                    handleChange={handleChange}
                    value={qty[item.name] ?? 0} 
                  />
                </td>
                <td>{item.price * (qty[item.name] ?? 0)}</td>
              </tr>
            ))}
          </tbody>
        </table>
        <button type='submit'>Submit</button>
      </form>
      <h1>total:{sum}</h1>
    </div>
  );
}

export default App;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 16:15:06