2017-01-17 2 views
0

Ich laufe in wirklich, wirklich seltsame Verhalten mit Redux. Grundsätzlich habe ich ein Spiel mit einer statischen Karte, wo der Spieler sich auf der Karte bewegt. Die Karte und der Spieler wird durch farbige div ‚s vertreten. Das ist alles, was ich versuche, und ich konnte es kurzzeitig zum Laufen bringen.Warum ist Redux der Lage, meine CONSTANT Ausgabe von einer Initialisierung Minderer zu ändern?

Ich erstelle die Bewegung, indem ich zuerst die leere Karte (die eine fest codierte const Array von Arrays ist) und dann die Position des Spielers (neu) an den richtigen Koordinaten hinzufügen. Dann rendere ich es auf die Ansichtsebene in React. Das ausgegebene neue Karte mit der Lage des Spielers ist nicht die gleiche wie die leere Karte genannt.

Aber etwas sehr komisches passiert mit Redux, wo es irgendwie ist, das das hartcodierte const Array von Feldern ändert, wenn ich es rende. Wenn Sie eine Menge console.logs verwenden, um zu sehen, was mit den Variablen passiert, bestätigen Sie, dass dies der Fall ist. Könnte jemand bitte einen Blick auf diese codepen haben:

http://codepen.io/swyx/pen/MJbezj?editors=1010

und lehre mich, wie auf der Erde zu verfolgen, was mit meinem wandelbar const ist da los?

EDIT: hier ist der entsprechende Code (constMap ist ein const Array von Arrays)

const InitMap = function() { 
    console.log('InitMap') 
    return constMap /// why is this changing every single time??? 
} 

dies später mit dem anderen Reduzierstücke kombiniert wird:

const rootReducer = combineReducers({ 
    gamemap: InitMap, 
    user: InitUser, 
    userMove: UserMove 
}); 

und dann in den jeweiligen verwendeten mapStateToProps Funktion:

function GMmapStateToProps(state){ 
    //from here goes into this.props 
    console.log('GMmapStateToProps') 
    console.log(state) 
    console.log(constMap) 
    var newgamemap = constMap, //state.gamemap also doesnt work, 
     newuser = state.user 
    console.log(newgamemap) 
    if (state.userMove) { 
    //check if is whitespace 
    var x2 = newuser.location.x + state.userMove.vector.x 
    var y2 = newuser.location.y + state.userMove.vector.y 
    if (newgamemap[y2][x2] === 1) { 
     newuser.location.x = x2 
     newuser.location.y = y2 
     //add user 
     newgamemap[newuser.location.y][newuser.location.x] = 9 
    } 
    } else {  
    //add user 
    newgamemap[newuser.location.y][newuser.location.x] = 9 
    } 
    console.log(newgamemap) 
    return{ 
    xgamemap: newgamemap, 
    user: newuser 
    } 
} 

was ist lächerlich ist der Wert von constMap ändert sich jedes Mal, wenn ich das nenne! Warum wie? Es bringt mich dazu, meine geistige Gesundheit in Frage zu stellen.

+2

Nur die Array-Referenz ist eine Konstante; Der Inhalt ist veränderbar. Dies gilt: const a = [1,2,3]; ein.Spleiß (0,3); "aber das ist nicht:" const a = [1,2,3]; a = []; 'Etwas mutiert Ihr Array, aber die' const'-Eigenschaft wird nicht die Laufzeit bekommen, um Ihnen zu helfen, zu finden, wo es mutiert ist. – cartant

+0

hey @cartant, danke für die Antwort. Ich war besorgt, dass dies eine seltsame Pointer vs Referenz Sache sein würde (ich dachte, das war ein C-Ding und keine Javascript-Sache). Gibt es eine Sache in Chrome Dev Tools, die mir helfen können, den Inhalt des Arrays zu verfolgen? – swyx

+2

Jetzt, da Sie den Code hinzugefügt haben, ist es klar, dass Sie ihn in 'GMmapStateToProps' mit den Änderungen, die Sie an' newgamemap' vornehmen, mutieren - was sich auf das gleiche Array bezieht. Sie haben Ihre Frage mit "redux" markiert, aber Sie sollten den Anwendungsstatus in einer Redux-Architektur nicht mutieren. – cartant

Antwort

2

Das ist, weil const nicht unveränderlich erstellen. Von MDN,

Die const-Deklaration erstellt einen schreibgeschützten Verweis auf einen Wert. Es bedeutet nicht, dass der Wert, den es enthält, unveränderlich ist, nur dass der Variablenbezeichner nicht neu zugewiesen werden kann. Wenn der Inhalt beispielsweise ein Objekt ist, bedeutet dies, dass das Objekt selbst noch geändert werden kann.

So gilt folgendes

const myArr = [] 
myArr.push(1) 
myArr = [1,2,3] //throw error 

const myObj = {} 
myObj['test'] = true 

Wenn Sie möchten, schauen Sie in Object.freeze

0

mit Hilfe des @ cartant - das Problem hier war, dass ich nicht wusste, dass JavaScript-Arrays geht und Objekte nach Referenz nicht nach Wert. Natürlich habe ich durch die Zuweisung eines anderen Namens zu meinem Array nichts getan, um das Endergebnis zu ändern. und natürlich hat javascript keine native tiefe kopie methode weil javascript. so dass ich denke, wenn künftig Menschen in diese laufen, gehen Sie einfach die tiefe Kopie Route: What is the most efficient way to deep clone an object in JavaScript?

Verwandte Themen