In redux challenge, don't know what is the difference

Tell us what’s happening:
Why I have to use
state = { login: true}
and I can’t use
state.login = true
what is the difference?
I check using console log , the results are same

Your code so far


const defaultState = {
login: false
};

const reducer = (state = defaultState, action) => {
// Change code below this line
if(action.type=='LOGIN'){
  state = {login: true};
  // state.login = true;
  return state;
}
return state;
// Change code above this line
};
const store = Redux.createStore(reducer);
const loginAction = () => {
return {
  type: 'LOGIN'
}
};

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36.

Challenge: Handle an Action in the Store

Link to the challenge:

That’s a core value of Redux: data must be immutable.

So to update its value, you need to manually make a copy and pass a new object; you cannot update (mutate) an existing value.

Why I have to use
state = { login: true}
and I can’t use
state.login = true

Technically neither is the right way. In the first case you are mutating your input variable., In the second case you are mutating a property of your input variable, mutating state. Never, ever mutate state. Everytime you do, a puppy dies. The right way would be to return the object that you want, the new state.

1 Like

actually I didn’t change the defaultState constant I only change the parameter of reducer function.

and I passed the challenge

I only change the parameter of reducer function.

Right, that is a questionable practice in general, but is definitely a bad thing in redux.

Redux is going to check to see if anything changed by checking the reference of the state object. If you go state.login = true;, then the reference to the object hasn’t changed - it is the same reference (or address), you just changed some data inside it. But > I only change the parameter of reducer function.

Redux is expecting a whole new reference so it can know that something has changed.

In the second example state = {login: true};, you are at least creating a new reference, but you are unnecessarily overwriting your parameter. There is no need to do that - just return that new state object. You can leave the parameter unchanged.

and I passed the challenge

The point isn’t to pass challenges, it is to learn good coding practice. Now, we try to write good tests that keep people from doing questionable things, but this test doesn’t check for this (yet, at least).

I don’t know what immutable mean, I think I didn’t change defaultState constant, is that what it mean is?

From the description text:

Another key principle in Redux is that state is read-only. In other words, the reducer function must always return a new copy of state and never modify state directly. Redux does not enforce state immutability, however, you are responsible for enforcing it in the code of your reducer functions. You’ll practice this in later challenges.

To mutate means to change.

let obj = { data: 1 };

obj.data = 2; // mutating

obj = { data: 3 }; // not mutating

In the first case, I used the same object but changed something in it - I mutated the existing object. In the second case, I created a whole new object and just replaced the old one.

Not mutating can be a good thing in many situations, but sometimes you want to. But in Redux (and React), you never, never, never mutate the state - it can cause things not to work.

1 Like

You have shadowed the state parameter, which is a questionable practice since it makes reading and debugging less obvious.

Think of this:

function sayHi(name) {
  name = "Kevin";
  console.log(`Hello ${name}`)
}

sayHi("Claudio")
// I would expect to be "Hello Claudio"
// but i get
// "Hello Kevin"

In the above example name gets shadowed by a variable in the function body.


Immutable is a simple programming principle where you don’t allow values to change.

var a = "hello";
a = 12;

The above is an example of a mutable program and is perfectly valid JS.
You have a variable a that has a string value, then you mutate it to be a number.

Redux discourage this pattern and guarantees that everything stays immutable, meaning that if I were to perform something similar in Redux, it will not work as the library won’t allow a to be mutated.
So in concept is closer to ES6:

const a = "Hello";
a = 12;

// TypeError!

I cannot reassign to a constant variable.

Hope it clarify a bit, as I see @kevinSmith is also providing a great insight :slight_smile:

1 Like

@Marmiz Just as a point of vocabulary, I wouldn’t call this a case of “shadowing”, which I have always understood to be declaring a variable in an inner scope that already exists in an available outerscope, as explained here. I would call this mutating an input parameter.

Now I’ve got the point, as Kevin said

and the reason why Redux did this is

these are new insight to me, thanks @kevinSmith and @Marmiz

1 Like

Yeah, redux is weird. But it’s also really cool once you get the hang of it.

1 Like