Реагируют на изменение реквизита неожиданно, когда переменная инициализируется как изменение реквизита - PullRequest
0 голосов
/ 25 января 2019

Я создал переменную и установил ее равной некоторым реквизитам.Когда я изменил свою переменную, реквизиты также изменились.Как изменить переменную без смены реквизита?

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

Но результат тот же, реквизитвсе еще изменяются.

Я ожидал, что переменная изменится, в то время как реквизит сохранит исходное значение.Но когда я меняю переменную, меняется и реквизит:

Снимок экрана

Ответы [ 2 ]

0 голосов
/ 30 мая 2019

Расширяя ответ Шубхэма, в памяти хранятся только примитивы (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 хранят указатели на позицию массива в памяти. Поэтому, когда вы изменяете позицию [0] на y, x видит «5» в позиции [0]. x -> [5,2] <-y </p>

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

Шубхам (я думаю) создает новое пространство в памяти с теми же значениями. Таким образом, обе переменные будут иметь разные указатели.

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

Однако, поскольку у вас есть массив внутри объекта, вы столкнулись с другой проблемой указателя ссылки. Вам нужно создать новый указатель, если вы хотите отредактировать новый массив, сохранив оригинал.

0 голосов
/ 25 января 2019

Проблема заключается в том, что назначение объекта работает по ссылке, а также распространяет синтаксис, просто клонирует объект на один уровень глубины, вам нужно обновить ваш объект как

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 (
        ...
    )
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...