当props初始化的变量发生变化时,React props发生意外更改

时间:2019-01-25 09:02:39

标签: javascript reactjs react-props

我创建了一个变量并将其设置为等于一些道具。当我更改变量时,道具也发生了变化。如何在不更改道具的情况下更改变量?

import React from 'react';
import { connect } from 'react-redux';

...

class TestApp extends React.Component {
    render() {
        var test = this.props.test;
        console.log("before change")
        console.log(test.name)
        console.log(this.props.test.name)

        // change the variable
        test.name[0] = 'pakpahan'


        console.log("after change")
        console.log(test.name)
        console.log(this.props.test.name)

        return (
            ...
        )
    }
}

...

const mapStateToProps = function (state) {
    return {
        test : {
            name : ['aldo', 'lino']
        }
    }
};


export default connect(mapStateToProps)(TestApp);

我已经尝试使用其他人提供的一些解决方案

var test = {...this.props.test};

但是结果是一样的,道具仍然在变化。

我希望变量在道具保留原始值的同时发生变化。但是当我更改变量时,道具也随之更改:

Screenshot

3 个答案:

答案 0 :(得分:1)

问题在于对象分配通过引用进行工作,并且传播语法也只是将对象克隆了一层,您需要像这样更新对象

render() {
    var test = {...this.props.test};
    console.log("before change")
    console.log(test.name)
    console.log(this.props.test.name)

    // change the variable
    const newName = [...test.name]
    newName[0] = 'Abc';
    newName[3] = 'GBG';
    test.name = newName;


    console.log("after change")
    console.log(test.name)
    console.log(this.props.test.name)

    return (
        ...
    )
}

答案 1 :(得分:0)

扩展Shubham的答案,只有原语(int,string,bool等)存储在内存中。非基元(数组,对象,函数)仅存储指向内存的指针。

因此原语会像您期望的那样起作用,因为它们实际上存储了值:

let a = 1;
let b = a;
b = 2;
console.log(a); // 1
console.log(b); // 2

虽然非原始元素实际上仅存储引用:

let x = [1, 2];
let y = x;
y[0] = 5;
console.log(x); //[5,2]

x和y都将指向数组位置的指针存储在内存中。因此,当您在y上更改位置[0]时,x在位置[0]上也会看到'5'。 x-> [5,2] <-y

https://medium.com/@junshengpierre/javascript-primitive-values-object-references-361cfc1cbfb0

Shubham(我认为)正在使用相同的值在内存中创建一个新空间。因此,这两个变量将具有不同的指针。

x = [1,2]; // x -> [1,2]
y = x;     // x -> [1,2] y -> [1,2]
y[0] = 5   // x -> [1,2] y -> [5,2]

对存储基元的对象执行此操作的另一种方法是创建一个新属性,以便您也可以保留旧值。

test = { 
    name : 'aldo'
}

test2 = test;
test2.newName = 'pakpahan';

console.log(test.name); // aldo
console.log(test2.newName) // pakpahan

但是,由于在对象内部有一个数组,因此遇到了另一个引用指针问题。如果要在保留原始数组的同时编辑新数组,则需要创建一个新指针。

答案 2 :(得分:0)

尝试:{...this.props.test}用于对象或[...this.props.test]用于数组