0

I have declared state like this,

 this.state = { filtersEnabled: false}

and later I destructured this object as follows,

let { filtersEnabled } = this.state;

Now, I want to change the value of filtersEnabled,

filtersEnabled = true

when I do console.log(this.state.filtersEnabled), The answer is => false,

But If I change the value as follows

 this.state.filtersEnabled = true

Now if I do when I do console.log(this.state.filtersEnabled), The answer is => true,

What's the problem here,

1.con't we do any assignment to destructured variables? or

2.con't we do any assignment to destructured state variables?

ThinkAndCode
  • 1,319
  • 3
  • 29
  • 60
  • 4
    `filtersEnabled` is just variable with a boolean value. Any reassignment to it will not affect `state` object. And you are [not supposed](https://reactjs.org/docs/state-and-lifecycle.html#using-state-correctly) to update state like this `this.state.filtersEnabled = true`. You need to use `setState` – adiga Dec 10 '20 at 06:29
  • 2
    Destructuring is completely irrelevant here, you'd have the same result with `let filtersEnabled = this.state.filtersEnabled;` JavaScript [is a pass by value language](https://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language), you don't get a reference to a primitive when you create a variable for it. – VLAZ Dec 10 '20 at 06:41

3 Answers3

2

When you are changing the value like this:

 this.state.filtersEnabled = true

You are changing the value of a property. But when you change the value like this:

 filtersEnabled = true

You basically assign a new value to filtersEnabled. There's no longer a reference to the original value.

Consider this example:

let a = 1;
let b = a;
a++;

Do you expect b to be 2? No, because ++, like += and = are all operators that create a new assignment.

This is also why we need let for these cases. const would not allow us to make changes.

This, however, does change both:

const a = { val: 1 };
const b = a;
a.val++;

b points to the same object. We never do a re-assignment of a (this is also why we can use const here), but we do reassign a property of a (and b). So still the same object, but we modified something inside the object.

Evert
  • 93,428
  • 18
  • 118
  • 189
2

In React when you want to update state you should pass via the this.setState method instead of mutating the state directly.

Do Not Modify State Directly

Performing destructuring of the this.state will create new variable based on values of different keys get from the Object which is destructured. That will loose any kind of coopling of element with Reference as only object keys can refered to their main reference where ever their are mutate.

let person = {
  "name": "John Doe",
  "age": 40
};

person.name = "Jeanne Doe";

console.log(person);

let { name } = person;
name = "Scott Duck"
console.log(person);

As you can see in the example abave after I have destructure the person Object the name variable isn't tight to the person Object any more, We loose the reference to the person.name property.

When you access filtersEnabled you are no longer accessing the value of component state with the same name but you are accessing the value which that variable hold at a specif time.

To keep tight to the value in the state use this.setState to mutate the state and access via this.state.filtersEnabled or with the structured value If you know that the value which is holded by created variable from destructuration will be same as value in the state, that can be done inside of the render as long as we know that the render method will most of time be executed when the state change.

Yves Kipondo
  • 5,289
  • 1
  • 18
  • 31
1

No. By destructing the variable it is converted into a local variable and the state is global so you need to do is this.state.filtersEnabled = true to reassign it globally in the state to use everywhere in the class.

By doing this.state.filtersEnabled = true It will reassing the value but if you need rerendering the view then you have to do like this.setState({ filtersEnabled: true});

Nooruddin Lakhani
  • 7,507
  • 2
  • 19
  • 39