4

In regards to my previous question (code is still giving me trouble): React: Javascript assignment not updating object

Code Here https://codesandbox.io/s/github/nieroda/js_err

You can see the object I have on line 2. There is no mutation that occurs between 2 and 5 although the print output is different (as seen below) leading me to believe that the code is being executed out of order.

codeBreaker.js:108

    1. console.log("BEFORE")
    2. console.log(gameBoardCopy[currentRow])
    3. console.log("END")

    let copy = this.state.gameBoard[currentRow].slice()

    4. console.log("Copy Start")
    5. console.log(copy)

    6. console.log("Before Assignment")
    copy[4] = { numColorMatch: 2, numExactMatch: 2 }
    7. console.log("After Assignment")

    8. console.log(copy)
    9. console.log("copy end")

Looking at the output

  1. BEFORE

2.

0: "BlueViolet"
1: "BlueViolet"
2: "BlueViolet"
3: "BlueViolet"
4: {numColorMatch: 0, numExactMatch: 0}
  1. END
  2. Copy Start

5.

    0: "BlueViolet"
    1: "BlueViolet"
    2: "BlueViolet"
    3: "BlueViolet"
    4: {numColorMatch: 2, numExactMatch: 2}
  1. Before Assignment
  2. After Assignment
  3.  0: "BlueViolet"
     1: "BlueViolet"
     2: "BlueViolet"
     3: "BlueViolet"
     4: {numColorMatch: 2, numExactMatch: 2} 
    
  4. copy end

I cant figure out what is causing this, tips appreciated. Thanks

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Nate
  • 81
  • 9
  • Are you logging this in your constructor? If so, try logging in `componentDidMount()`. Let me know the result. This happened to me once before, don't remember what I did yet though. – Miroslav Glamuzina Mar 01 '19 at 05:04
  • In my onclick function https://codesandbox.io/s/github/nieroda/js_err feel free to check out the code here codeBreaker.js:108 – Nate Mar 01 '19 at 05:10

2 Answers2

3

console.log is actually an async method and that is most likely why you are seeing the execution "appear" out of order. Whenever you console.log an object, make sure to console.log(JSON.stringify(JSON.parse(value)));.

A better way to see execution order and its values is to add debugger statement. Try adding debugger; right above step 5 and walk through the code to see what the values actually are. I would imagine the values would be as you expect them to be. If not, stepping through the process using the debugger will tell you why.

dericcain
  • 2,182
  • 7
  • 30
  • 52
1

Looks like you are unintentionally mutating the state of your component. You are not copying the object here. Javascript objects are passed by reference, which means when you directly assign an object like this to another variable, they both will modify the same data.

Instead of:

let copy = this.state.gameBoard[currentRow].slice()

call:

let copy = Object.assign({}, this.state.gameBoard[currentRow]);

If it is your intention to update the state of your component you should call the.setState({obj}).

If you have to deep clone an object, I would suggest deep copy functions from either lodash or underscore (or create your own: Objects in JS: deep copy).

Hope this helps,

Miroslav Glamuzina
  • 4,472
  • 2
  • 19
  • 33