【问题标题】:Array with prototypes changing the redux state带有改变 redux 状态的原型的数组
【发布时间】:2019-08-16 15:36:07
【问题描述】:

我在使用 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

它有数组原型,对应于可以应用于数组的方法,但在数组原型之外它还有其他方法。当数组像这样出现时,我想用某种方法更改数组或使用数组作为值来更改组件的状态,它会在不调度 redux 操作的情况下更改 redux 状态。假设 redux props 是只读的,但这是在不调度操作的情况下更改 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 状态,这是不应该发生的事情。 为什么会发生这种情况以及如何避免这种情况?为什么数组会采用这种格式?

【问题讨论】:

  • 在此处添加更多代码示例
  • 准备好了,我放一个redux store发生变化的情况。
  • 我们能看到你的 reducer 和对应 redux 字段的操作吗

标签: javascript reactjs redux


【解决方案1】:

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

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 一样。

【讨论】:

猜你喜欢
  • 2019-04-29
  • 2019-03-19
  • 1970-01-01
  • 2021-07-31
  • 2019-02-03
  • 2019-01-30
  • 1970-01-01
  • 2021-12-30
  • 2020-09-18
相关资源
最近更新 更多