简体   繁体   English

带有原型的阵列更改Redux状态

[英]Array with prototypes changing the redux state

I'm using redux in a React application in which I use ChartJS library to make charts. 我在React应用程序中使用Redux,在其中我使用ChartJS库制作图表。 I have noted that sometimes when I take an array from the global redux state, it comes like this: 我已经注意到,有时当我从全局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

It has the array prototypes, which correspond to the methods that one can apply over an array, but outside of the Array prototype it has another methods. 它具有数组原型,对应于可以应用于数组的方法,但是在数组原型之外,它具有另一种方法。 When the array comes like this, and I want to change the array with some method or change the state of a component using the array as value, it changes te redux state without dispatching an redux action. 当数组是这样的,并且我想用某种方法更改数组或使用数组作为值更改组件的状态时,它会更改redux状态而无需调度redux操作。 It's supposed that the redux props are read only, but this is changing the redux state without dispatching an action. 假设redux道具是只读的,但这改变了redux的状态而没有调度动作。 For example, I sort two array using this method: 例如,我使用此方法对两个数组进行排序:

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) }
        }

And then I use the new sorted array for changing a react component props cloning the component and using the new sorted array as props: 然后,我使用新的排序数组来更改react组件props克隆组件并将新的排序数组用作props:

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) });
        }

Before setting the state in the cambiarGraficas method, the redux state not change, as it should be, but when I set the state of graficas to the new array with the component with the new props, is when it changes the redux state without dispatching a action, thing that should not happen. 在使用cambiarGraficas方法设置状态之前,redux状态不会发生应有的变化,但是当我将graficas的状态设置为带有新道具的组件的新数组时,它是在更改redux状态而未调度a的情况下行动,不应该发生的事情。 Why is this happening and how can avoid this? 为什么会发生这种情况,如何避免这种情况发生? Why the arrays is coming with this format? 为什么数组采用这种格式?

Seems like, that you copy pointers and changing values of stuff that you didn't mean to do. 好像您复制了指针并更改了您本不想做的事情的值。 When you do something like: 当您执行以下操作时:

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

Into the elemento1 you get the pointer of the item in the array1[j] Which means that when you later on take this list and do with it something, you basicly change the original data source of array 1. elemento1您将获得array1[j]中该项的指针,这意味着以后再使用此列表并对其进行处理时,基本上就可以更改数组1的原始数据源。

Same happens when you use React.cloneElement . 当您使用React.cloneElement时, React.cloneElement发生同样的情况。 it creates a shallow copy: 它创建一个浅表副本:

"Clone and return a new React element using element as the starting point. The resulting element will have the original element's props with the new props merged in shallowly" “使用element作为起点克隆并返回一个新的React元素。生成的元素将具有原始元素的props,而新的props则浅层合并。”

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

For your solution, i link you here: https://medium.com/@gamshan001/javascript-deep-copy-for-array-and-object-97e3d4bc401a Where you can see the defference of deep copy and shallow copy. 对于您的解决方案,我在这里链接您: https : //medium.com/@gamshan001/javascript-deep-copy-for-array-and-object-97e3d4bc401a在这里您可以看到深层复制和浅层复制的差异。

At the entry of you copy function, you can use Array.from() 在复制功能的入口处,可以使用Array.from()

For array we will use 'Array.from()'. 对于数组,我们将使用“ Array.from()”。 The Array.from() method creates a new Array instance from an array-like or iterable object. Array.from()方法从类似于数组或可迭代对象的对象创建一个新的Array实例。

Changing the real data, with shallow copies can create lots of headache as well with redux. 使用浅拷贝来更改实际数据也会给redux带来很多麻烦。

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

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