首页 > 解决方案 > 带有改变 redux 状态的原型的数组

问题描述

我在使用 ChartJS 库制作图表的 React 应用程序中使用 redux。我注意到有时当我从全局 redux 状态中获取一个数组时,它是这样的:

 ejeY: Array(7)
    0: 43783
    1: 85001
    2: 100960
    3: 75271
    4: 22117
    5: 27542
    6: 0
    length: 7
    pop: ƒ ()
    push: ƒ ()
    shift: ƒ ()
    splice: ƒ ()
    unshift: ƒ ()
    _chartjs: {listeners: Array(1)}
    __proto__: Array(0)
    __proto__: Object

它具有数组原型,它们对应于可以应用于数组的方法,但在 Array 原型之外它还有另一种方法。当数组出现这样的情况时,我想用某种方法更改数组或使用数组作为值来更改组件的状态,它会在不调度 redux 操作的情况下更改 redux 状态。假设 redux 道具是只读的,但这是在不调度操作的情况下更改 redux 状态。例如,我使用这种方法对两个数组进行排序:

sortMaxToMinEjeX: (array1, array2) => {
            var list = [];
            for (var j = 0; j < array2.length; j++)
                list.push({ 'elemento1': array1[j], 'elemento2': array2[j] });
            list.sort((a, b) => {
                return ((a.elemento1 > b.elemento1) ? -1 : ((a.elemento1 === b.elemento1) ? 0 : 1));
            });
            for (var k = 0; k < list.length; k++) {
                array1[k] = list[k].elemento1;
                array2[k] = list[k].elemento2;
            }
            return { ejeY: Object.values(array2), ejeX: Object.values(array1) }
        }

然后我使用新的排序数组来更改反应组件道具克隆组件并使用新的排序数组作为道具:

cambiarGrafica: ({ labels, datasets }) => {
            console.log(labels, datasets);
            const { graficas, indice } = this.state;
            let nuevasGraficas = graficas.filter((componente, index) => index !== indice);
            let graficaSeleccionada;
            if (datasets) {
                graficaSeleccionada = React.cloneElement(graficas[indice], { labels, datasets });
            } else {
                graficaSeleccionada = React.cloneElement(graficas[indice], { labels });
            }
            nuevasGraficas.splice(indice, 0, graficaSeleccionada);
            this.setState({ graficas: Object.values(nuevasGraficas) });
        }

cambiarGraficas方法中设置状态之前,redux 状态不会改变,因为它应该是,但是当我graficas使用带有新道具的组件将状态设置为新数组时,它会在没有调度动作的情况下改变 redux 状态,不应该发生的事情。为什么会发生这种情况以及如何避免这种情况?为什么数组以这种格式出现?

标签: javascriptreactjsredux

解决方案


似乎,您复制了指针并更改了您不想做的事情的值。当您执行以下操作时:

list.push({ 'elemento1': array1[j], 'elemento2': array2[j] });

进入elemento1你会得到项目的指针,array1[j] 这意味着当你以后拿这个列表做一些事情时,你基本上改变了数组 1 的原始数据源。

当您使用React.cloneElement. 它创建一个浅拷贝:

“使用元素作为起点克隆并返回一个新的 React 元素。生成的元素将具有原始元素的道具与新道具的浅层合并”

https://reactjs.org/docs/react-api.html#cloneelement

对于您的解决方案,我在此处链接您: https : //medium.com/@gamshan001/javascript-deep-copy-for-array-and-object-97e3d4bc401a 您可以在其中看到深拷贝和浅拷贝的区别。

在您复制功能的入口处,您可以使用Array.from()

对于数组,我们将使用 'Array.from()'。Array.from() 方法从类数组或可迭代对象创建一个新的 Array 实例。

使用浅拷贝更改真实数据也会引起很多麻烦,就像使用 redux 一样。


推荐阅读