1

I'm studying React and find some confusing thing with setState.

Let's say our state's object has property(todos) === array with objects. I create handleChange function to change state. Here's trickiest part.

handleChange creates another array inside 'arrPrev' - which is clone of original state(no reference), then i change something in 'arrPrev' -> '+= 1', and return empty object in handleChange.

Why second div in render '{this.state.todos[0].text}' change it's data and re-render, but i returned empty object above and didn't change anything in state.

import React from "react"

class App extends React.Component {
    constructor() {
        super()
        this.state = {
            todos: [
                {
                    id: 1,
                    text: "Take out the trash",
                    completed: true
                },
                {
                    id: 2,
                    text: "Grocery shopping",
                    completed: false
                },
                {
                    id: 3,
                    text: "Clean gecko tank",
                    completed: false
                },
                {
                    id: 4,
                    text: "Mow lawn",
                    completed: true
                },
                {
                    id: 5,
                    text: "Catch up on Arrested Development",
                    completed: false
                }
            ]
        }
        this.handleChange = this.handleChange.bind(this)
    }

    handleChange(id) {
        this.setState(prevState => {
            let arrPrev = prevState.todos.slice();
            arrPrev[0].text += '1';
            return {}
        })
    }

    render() { 
        return (
            <div className="todo-list">
                <div onClick={this.handleChange}>{this.state.todos[0].id}</div>
                <div>{this.state.todos[0].text}</div>
                <div>{this.state.todos[0].completed}</div>
            </div>
        )    
    }
}

export default App
sandbox992
  • 63
  • 6
  • Why do you change it at all if you don't want to change it? – Jonas Wilms Jan 22 '19 at 16:45
  • You should better specify what you ask, it is not very clear from your question... – MarcoS Jan 22 '19 at 16:47
  • 1
    regarding slice: For object references (and not the actual object), slice copies object references into the new array. Both the original and new array refer to the same object. If a referenced object changes, the changes are visible to both the new and original arrays. more detail [source](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice#Description) – Sahil Raj Thapa Jan 22 '19 at 17:47
  • regarding returning empty object in `this.setState`: if you return `{}` then full state is returned. As from above comment you know for object references using `slice` changes in one array can be seen on both the arrays. So in your state too `this.state.todos[0].text` is changed – Sahil Raj Thapa Jan 22 '19 at 17:54
  • @JS Engine create full answer, so i can mark it as 'answer' – sandbox992 Jan 22 '19 at 18:18
  • this question has been marked as duplicate so we can't answer in it. But did you get what i mean in the comments? – Sahil Raj Thapa Jan 22 '19 at 18:23
  • yeah, absolutely! Thnx) – sandbox992 Jan 22 '19 at 18:24
  • It's my pleasure. Alright then cheers !!!! :) – Sahil Raj Thapa Jan 22 '19 at 18:27

0 Answers0