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.
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.
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.
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).
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.
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.
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
@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.