如何使用react-redux处理使用map方法渲染的多个输入字段?

dgiusagp  于 2023-10-19  发布在  React
关注(0)|答案(2)|浏览(133)

我在json-server中有一个产品列表(没有数量),使用react-redux获取并在table中呈现。我也有一个输入字段从用户获得数量,通过乘以产品价格(从json-server)与产品数量(从输入字段)来计算总数。
列表中显示NaN的总计字段。问题出在 qty 上。如何避免这种错误?如何将表中所有输入字段初始状态初始化为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;
    setQty({
      ...qty,
      [name]:value 
    });
  }

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

  let sum = 0

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

  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]} 
                  />
                </td>
                <td>{item.price * qty[item.name]}</td>
              </tr>
            ))}
          </tbody>
        </table>
        <button type='submit'>Submit</button>
      </form>
      <h1>total:{sum}</h1>
    </div>
  );
}

export default App;

我尝试设置初始状态为数量。我希望所有输入字段都是数字0,而不是字符串或未定义

cx6n0qe3

cx6n0qe31#

这是因为这条线

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

最初qty是一个空对象,因此在上面的循环中qty[item.name]将抛出undefined
您需要将此迭代可能放在handleChange函数中,或者在qty有数据后重新启动列表

wlsrxk51

wlsrxk512#

把它放在handleChange中是行不通的,因为当这个函数运行时,它仍然只能访问qty状态的前一个版本,而qty状态仍然是一个空对象。
一个简单的解决方法是在求和时添加存在检查:

let sum = 0;
list.forEach((item) => {
  if (qty.hasOwnProperty(item.name)) {
    sum += item.price * qty[item.name];
  } else {
    // however you want to handle the default case here
  }
});

相关问题