在添加一些之前使用 UseState 重置值

时间:2021-07-08 06:48:20

标签: reactjs react-hooks use-state

我无法让 setMajorsetMinor 在函数内工作。

发生的情况是,它只是覆盖了 major 中的一些数据,并继续在 minor 中添加数据

我使用这段代码清除了 major 中的所有值,但它有点乱,而且看起来我没有正确使用 useState 函数。

major.forEach((tk) => {
      tk['material'] = ''
      tk['required'] = 0
      tk['actual'] = 0
      tk['difference'] = 0
      tk['crit'] = 0
      tk['percent'] = 0
    })

handleSelectInput 是一个 select tag,每当我更改值时,它都会向服务器发送请求以获取 majorminor 变量的正确值< /p>

const majorStates = [
      {
        tank: 1,
        material: '',
        required: 0,
        actual: 0,
        difference: 0,
        crit: 0,
        percent: 0,
      },
      {
        tank: 2,
        material: '',
        required: 0,
        actual: 0,
        difference: 0,
        crit: 0,
        percent: 0,
      },...10],
[major, setMajor] = useState(tankStates),
[minor, setMinor] = useState([]),

const handleSelectInput= async (e) => {
    const { name, value } = e.target

    setMajor(majorStates) // not working
    setMinor([]) // not working

    await axios
      .put(`${PATH}/main-start`, { product: value })
      .then((res) => {
        for (let i = 0; i < res.data.length; i++) {
          //See if data has a type major or minor
          //ParseFloat for decimal that's been returned as str
          if (res.data[i].type === 'MAJOR') {
            major[i].material = res.data[i].material
            major[i].required = parseFloat(res.data[i].required_wt)
            setMajor([...major])
          } else {
            res.data[i].required_wt = parseFloat(res.data[i].required_wt)
            setMinor([...minor, res.data[i]])
          }
        }
      })
      .catch((err) => {
        console.log(err)
      })
  }

我有一个 majorStates,因为即使提取数据小于 10,也要求显示 10 值。

对不起,如果这是一个菜鸟问题

1 个答案:

答案 0 :(得分:1)

问题

基于在循环中对一堆状态更新进行排队,我将猜测不起作用的是只有最后一次排队的状态更新才是您所看到的。这是因为每次循环迭代都从相同的陈旧状态开始。

您也在改变状态,例如,major[i].material = res.data[i].material 正在改变索引 major 处的 i 元素。

解决方案

使用功能状态更新从前一个状态更新,不是前一个渲染周期的状态。浅拷贝数组然后还浅拷贝任何正在更新的嵌套状态/元素。

const handleSelectInput= async (e) => {
  const { name, value } = e.target

  setMajor(majorStates) // reset
  setMinor([]) // reset

  await axios
    .put(`${PATH}/main-start`, { product: value })
    .then((res) => {
      for (let i = 0; i < res.data.length; i++) {
        //See if data has a type major or minor
        //ParseFloat for decimal that's been returned as str
        if (res.data[i].type === 'MAJOR') {
          setMajor(major => major.map((el, index) => index === i ? {
            ...el,
            material: res.data[i].material,
            required: parseFloat(res.data[i].required_wt)
          } : el);
        } else {
          res.data[i].required_wt = parseFloat(res.data[i].required_wt)
          setMinor(minor => [...minor, res.data[i]])
        }
      }
    })
    .catch((err) => {
      console.log(err)
    })
}