简体   繁体   English

当我在 React useState 中更新数组时,它一直默认为初始 state。 我究竟做错了什么?

[英]When I am updating an array in React useState, it keeps defaulting to the initial state. What am I doing wrong?

I have a state array, monthlyIncidents, and inside of this array are 12 numbers that I want to update based on some condition met.我有一个 state 数组,monthlyIncidents,这个数组里面有 12 个数字,我想根据满足的某些条件进行更新。 After researching online, I found that one way to accomplish this was to copy the array, update the element, and then finally update the state.在网上研究后,我发现完成此操作的一种方法是复制数组,更新元素,然后最后更新 state。 I tried this, however it is not working correctly.我试过这个,但是它不能正常工作。

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

In my useEffect implementation, I am looping over a set of records (a total of 3 times), and I want to update whatever element is at position 'incidentMonth' of the monthlyIncidents array.在我的 useEffect 实现中,我正在循环一组记录(总共 3 次),并且我想更新每月事件数组的 position 'incidentMonth' 处的任何元素。 Furthermore, from my dummy data I know that at the end of the loop, the element at index 7 (August) should have a value of 3.此外,从我的虚拟数据中,我知道在循环结束时,索引 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])

This is what my handleUpdate function looks like:这是我的 handleUpdate function 的样子:

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

I will now post the output found in the console.我现在将发布在控制台中找到的 output。 somehow monthlyIncidents is going back to its initial state (where all elements are storing 0不知何故,每月事件正在回到它最初的 state (所有元素都存储 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]


The entire component as requested根据要求的整个组件

 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

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

No need for a handleUpdate function无需手柄更新 function

Credit to: amakhrov归功于:阿马赫罗夫

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM