React道具在使用highcharts时被覆盖



我有一个react组件,它接收两个输入:data和normalizer。

<ChartInterface
normalizer={[10, 10, 10, 10]}
data={[
{ name: "lineA", data: [2, 1, 1, 2] },
{ name: "lineB", data: [1, 0, 3, 0] }
]}
/>

ChartInterface组件应该呈现一个复选框和一个图表;如果没有选中复选框,它应该只呈现一个包含数据的图表,这很好;如果复选框被选中,组件应该将所有data数组除以normalizer数组,我已经编写了这样做的函数。

然而,问题是,当我反复选中和取消选中此复选框时,数据会一次又一次地被数组分割。

只有当我添加<HighchartsReact options={chartOptions} highcharts={Highcharts} />组件时才会出现这个问题,如果我注释掉它并只打印chartOptions.lineData,复选框就会按预期工作。(勾选复选框显示标准化数据,取消勾选显示原始数据作为道具(

ChartInterface组件:

const ChartInterface = (props) => {
// state for checkbox if chart needs to be normalized or not
const [isNormalized, setIsNormalized] = useState(false);
//divides one array by another, element-wise
function normalize(a, b) {
return a.map(function (x, idx) {
return x / b[idx];
});
}
// get data for lines
let lineData = props.data;
//if normalized is checked, normalize the data
if (isNormalized) {
lineData = lineData.map((line) => {
return {
name: line.name,
data: normalize(line.data, props.normalizer)
};
});
}
// Chartoptions for highcharts, here we add the line data
const chartOptions = {
chart: { type: "area" },
xAxis: {
type: "category",
crosshair: true
},
plotOptions: {
area: {
stacking: "normal",
lineWidth: 1
}
},
series: lineData
};
return (
<>
<input
type="checkbox"
checked={isNormalized}
onChange={(e) => setIsNormalized(e.target.checked)}
/>
Normalise the data ?
{<HighchartsReact options={chartOptions} highcharts={Highcharts} />}
{JSON.stringify(lineData)}
</>
);
};

我还做了一个代码沙盒的例子,通过选中和取消选中复选框,你可以很容易地看到问题是什么:问题的代码沙盒演示感谢您的帮助

尝试通过更新状态来更改数据。如何做到这一点,您可以在这里找到:https://stackblitz.com/edit/react-6qlksy?file=index.js

请参阅此更新的codesandbox链接。出于某种原因,Highcharts正在改变你的lineData。可能有更好的方法,但通过使用lodash的cloneDeep,您可以看到,在传递到Highcharts选项之前对数据进行深度复制时,它是有效的。

因此,您的实际问题在于在第一次渲染时(禁用复选框时(将props.data的引用传递给chartOptions.series

let lineData = props.data

在这里,您复制了props.data的引用,然后不更改它,因为您的If已进入,然后您创建了chartOptions,其中series=props.data。因此,当您将Highchars系列引用到您的道具时。数据-当您更改一个时,即更改另一个。

现在好的问题是,为什么稍后重新渲染引用时,新对象不会覆盖引用,而Highchart却在改变初始对象。事实证明,这是Highchart组件优化,仔细查看他们的代码(https://github.com/highcharts/highcharts-react/blob/master/src/HighchartsReact.js)您可以看到,他们并没有重新创建组件,而是在执行chartRef.current.update,而不是简单地说options=newOptions,而是逐个属性并更改初始对象,如果您的初始对象实际上是您自己的props.data

要解决这个问题,你需要对props.data进行深度复制,而不是像Charlies在之前的回答中所建议的那样,只对lineData=props.data

最新更新