【问题标题】:When I am updating an array in React useState, it keeps defaulting to the initial state. What am I doing wrong?当我在 React useState 中更新一个数组时,它一直默认为初始状态。我究竟做错了什么?
【发布时间】:2026-02-18 00:15:01
【问题描述】:

我有一个 state 数组,monthlyIncidents,这个数组里面有 12 个数字,我想根据满足的某些条件来更新它们。在网上研究后,我发现实现此目的的一种方法是复制数组,更新元素,然后最后更新状态。我试过了,但它不能正常工作。

const [monthlyIncidents, setMonthlyIncidents] = useState([
    // monthlyIncidents[0] -> January ... monthlyIncidents[11] -> December
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
  ])

在我的 useEffect 实现中,我正在循环一组记录(总共 3 次),并且我想更新位于monthlyIncidents 数组的“incidentMonth”位置的任何元素。此外,根据我的虚拟数据,我知道在循环结束时,索引 7(8 月)处的元素的值应为 3。

useEffect(() => {
    if (data === undefined || isLoading) {
      console.log('data is undefined')
    } else {
      const totalIncidents: number = data.length
      for (let incident = 0; incident < totalIncidents; incident += 1) {
        let incidentMonth = getIncidentMonth(data[incident].reportedOn)
        handleUpdate(incidentMonth)
      }
    }
  }, [data])

这就是我的 handleUpdate 函数的样子:

const handleUpdate = (incidentMonth: number) => {
    console.log(monthlyIncidents: ", monthlyIncidents)
    var newMonthlyIncidents = [...monthlyIncidents]
    newMonthlyIncidents[incidentMonth] += 1
    console.log("newMonthlyIncidents: ", newMonthlyIncidents)
    setMonthlyIncidents(newMonthlyIncidents)
  }

我现在将发布在控制台中找到的输出。 somehow monthlyIncidents is going back to its initial state (where all elements are storing 0

iteration number  0
VisualizeIncidents.tsx:29 monthlyIncidents: (12) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
VisualizeIncidents.tsx:32 newMonthlyIncidents:  (12) [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
VisualizeIncidents.tsx:48 iteration number  1
VisualizeIncidents.tsx:29 monthlyIncidents: (12) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
VisualizeIncidents.tsx:32 newMonthlyIncidents:  (12) [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
VisualizeIncidents.tsx:48 iteration number  2
VisualizeIncidents.tsx:29 monthlyIncidents: (12) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
VisualizeIncidents.tsx:32 newMonthlyIncidents:  (12) [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]

请求的整个组件

import React, { useEffect, useState } from 'react'

import useIncidents from '../hooks/useIncidents'
import IncidentFilter from '../IncidentFilter'
import IncidentSearchRequest from '../model/IncidentSearchRequest'

const VisualizeIncidents = () => {
  const searchFilter = IncidentFilter.reported
  const searchRequest: IncidentSearchRequest = { status: searchFilter }
  const { data, isLoading } = useIncidents(searchRequest)
  const [monthlyIncidents, setMonthlyIncidents] = useState([
    // monthlyIncidents[0] -> January ... monthlyIncidents[11] -> December
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
  ])

  const handleUpdate = (incidentMonth: number) => {
    var newMonthlyIncidents = [...monthlyIncidents]
    newMonthlyIncidents[incidentMonth] += 1
    console.log('newMonthlyIncidents: ', newMonthlyIncidents)
    console.log('monthlyIncidents before:', monthlyIncidents)
    setMonthlyIncidents(newMonthlyIncidents)
    console.log('monthlyIncidents after:', monthlyIncidents)
  }

  const getIncidentMonth = (reportedOn: string) => {
    // reportedOn: "2020-08-12T19:53:30.153Z"
    return Number(reportedOn.slice(5, 7)) - 1
  }

  useEffect(() => {
    if (data === undefined || isLoading) {
      console.log('data is undefined')
    } else {
      const totalIncidents: number = data.length
      for (let incident = 0; incident < totalIncidents; incident += 1) {
        const incidentMonth = getIncidentMonth(data[incident].reportedOn)
        console.log('iteration number ', incident)
        handleUpdate(incidentMonth)
      }
    }
  }, [data])

  // console.log("after updating: ", monthlyIncidents)

  return (
    <>
      <LineGraph
        datasets={[
          {
            backgroundColor: 'blue',
            borderColor: 'black',
            data: [
              {
                x: 'January',
                y: 12,
              },
              {
                x: 'February',
                y: 11,
              },
              {
                x: 'March',
                y: 10,
              },
            ],
            label: 'Incidents',
          },
        ]}
        title="Reported Incidents Overtime"
        xAxes={[
          {
            label: 'Months',
            type: 'category',
          },
        ]}
        yAxes={[
          {
            label: 'Numbers',
            type: 'linear',
          },
        ]}
      />
    </>
  )
}

export default VisualizeIncidents

【问题讨论】:

  • handleUpdate 是做什么的?你能发布你的整个react 组件吗?
  • handleUpdate 将 'incidentMonth' 作为参数(其中incidentMonth 是从 0 到 11 的某个数字)并将该位置的元素的值增加一(如某种计数器)
  • 我现在也会发布整个组件
  • 我相信我对 setMonthlyIncidents 的使用可能不正确。有人可以确认吗?因为在该行执行后,console.log(monthlyIncidents) 显示它没有改变
  • Check this setMonthlyIncidents 一切正常。问题是它获取的数据可能是错误的。

标签: javascript reactjs typescript react-hooks use-state


【解决方案1】:

setMonthlyIncidents((prevIncidents) => {
   return { ...prevIncidents, [incidentMonth]: monthlyIncidents[incidentMonth] += 1 }
})

不需要handleUpdate函数

感谢:amakhrov

资源:reactjs.org/docs/hooks-reference.html#functional-updates

【讨论】: