3
votes

Les props React changent de manière inattendue lorsqu'une variable initialisée en tant que props change

J'ai créé une variable et l'ai définie égale à certains accessoires. Lorsque j'ai changé ma variable, les accessoires ont également changé. Comment changer la variable sans changer les accessoires?

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

J'ai déjà essayé d'utiliser certaines solutions fournies par d'autres

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

Mais le résultat est le même, les accessoires changent toujours.

Je m'attendais à ce que la variable change tandis que les accessoires conservent la valeur d'origine. Mais lorsque je change la variable, les accessoires changent également:

Capture d'écran a >


0 commentaires

3 Réponses :


3
votes

Le problème est que l'attribution d'objet fonctionne par référence et que la syntaxe de diffusion ne fait que cloner l'objet d'un niveau de profondeur, vous devez mettre à jour votre objet comme

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 commentaires

Merci! c'est génial, je ne savais même pas comment ça marche. Mais vous savez, il ne résout le problème qu'avec le changement sur le premier tableau, comment résoudre le problème s'il y a 10 éléments sur le tableau, et je veux changer le tableau uniquement les numéros 2,4 et 6?



0
votes

En développant la réponse de Shubham, seules les primitives (int, string, bool, ...) sont stockées en mémoire. Les non-primitives (tableau, objet, fonction) ne stockent que des pointeurs vers la mémoire.

Les primitives agissent donc comme vous attendez de la variable car elles stockent en fait la valeur:

test = { 
    name : 'aldo'
}

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

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

Alors que les non-primitives ne stockent en réalité qu'une référence:

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

Les deux x et y stockent des pointeurs vers la position du tableau en mémoire. Ainsi, lorsque vous changez la position [0] sur y, x voit également '5' à la position [0]. x -> [5,2]

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

Shubham crée (je pense) un nouvel espace en mémoire avec le mêmes valeurs. Ainsi, les deux variables auront des pointeurs différents.

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

Une autre façon de faire cela sur un objet stockant des primitives serait de créer une nouvelle propriété afin que vous puissiez également conserver l'ancienne valeur.

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

Cependant, comme vous avez un tableau à l'intérieur d'un objet, vous rencontrez un autre problème de pointeur de référence. Vous devez créer un nouveau pointeur si vous souhaitez éditer le nouveau tableau tout en préservant l'original.


0 commentaires

0
votes

Essayez: {... this.props.test} pour un objet ou [... this.props.test] pour un tableau


0 commentaires