我在功能组件中使用useState
钩子来存储数据。然而,我想以另一个单位显示数据。因此,在将数据提供给组件之前,我会对数据进行计算。然而,看起来计算被保存在状态变量中,并且由于react时不时地渲染组件,因此数据被多次除以1000。就我所见,我没有在初始赋值后调用setState函数(setPriceData
),也没有改变状态变量(priceData
)本身。
My Minimal reproducibility Example:
import React, { useEffect, useState } from "react"
import MyComponent from "MyComponent"
const PriceGraph = () => {
const [priceData, setPriceData] = useState<Array<{ x: Date, y: number }>>([])
useEffect(() => {
const data = [
{
x: new Date("2023-04-04T13:00:00"),
y: 108.71
},
{
x: new Date("2023-04-04T14:00:00"),
y: 112.73
}
]
setPriceData(data)
}, [])
return (
<div>
<MyComponent data={getChartData(priceData)} />
<span>
{priceData[0]?.y}
</span>
</div>
)
}
function getChartData(data: Array<{ x: Date, y: number }>) {
return {
datasets: [
{
data: mwhToKwh(data),
},
],
}
}
function mwhToKwh(data: Array<{ x: Date, y: number }>) {
return data.map(point => {
point.y /= 1000
return point
})
}
export default PriceGraph
预期的结果是,当React呈现并重新计算原始数据(priceData
)的转换时,跨度中的数据随着时间的推移保持不变。然而,实际的结果是,每次渲染时打印的数据都变小了1000倍。这怎么可能呢?我是否错过了React生命周期或钩子行为?
正如Thomas正确指出的那样,我引用point.y
并将其设置为自身除以1000。因为这是一个引用变量,而不是(深度)克隆,所以状态变量被改变了。
解决方案:深度克隆或者,因为它是一个简单的对象:
function mwhToKwh(data: Array<{ x: Date, y: number }>) {
return data.map(point => {
return {x: point.x, y: point.y / 1000}
})
}