Handle an Action in the Store REDUX

Tell us what’s happening:

the one error I am getting.

“Dispatching loginAction should update the login property in the store state to true.”

^

I’ve watched a few tutorials on Redux and they all mention payloads, how can I set my store.dispatch({type: loginAction to make my login property = true?

Your code so far


const defaultState = {
  login: false
};

const reducer = (state = defaultState, action) => {
  // change code below this line
  if(action.type === 'LOGIN'){
    return state;
  }
  return state
  // change code above this line
};

const store = Redux.createStore(reducer);

const loginAction = () => {
  return {
    type: 'LOGIN'
  }
};

store.dispatch({type: loginAction})

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/front-end-libraries/redux/handle-an-action-in-the-store/

In you reducer, if the action is of type ‘LOGIN’ you should return an object with the login field set to true. Also you don’t need the store.dispatch() statement at the end.

1 Like

Dispatching loginAction should update the login property in the store state to true.

This is done in the reducer function?

Payload is what we call the data you want to work with. It’s any property besides the type in the action. So

const defaultState = {
  login: false
};

// this is your action creator
const loginAction = () => {
// all you do here is configure the data into the shape you want
// to work with, so that later you know how to access it
  return {
    type: 'LOGIN',
    myData: 'some data'
  }
};

which returns an action object of this shape…

{
  type: 'LOGIN',
  myData: 'some data'
}

that gets sent into the reducer

const reducer = (state = defaultState, action) => {
  // here you receive a state object
state = {
   login: false
 }

// and an action object
action = {
  type: 'LOGIN',
  myData: 'some data'
 }
}

Using dot notation, e.g action.type, you check if this reducer should update and return a new state, or if it should skip this action and return the state passed in.

That means this reducer will get every action sent to it. The same is true for all the reducers. So make sure to check for only the action.type you want to handle in this function

Tell me if there’s something I didn’t explain well, and I’ll give it another go.

3 Likes

image

What am I doing wrong ?
error message : Dispatching loginAction should update the login property in the store state to true.

Your reducer can only do 1 of two things

  1. return the state, untouched
  2. update the state, and return the updated state

There’s one caveat though. The reducer can not mutate state. This means doing something like the following will not work.

state.login = true

//
return state

Here you are changing the value of the login prop, and returning the same object.

Instead, you have to create a clone of the state and change that. In pseudo code it looks like

const stateClone = state
stateClone.updatedValue = updatedValue

return stateClone

I’ll give you a hint to get you started. Read this page carefully because there’s a gotcha in there that’s easy to overlook.

Tell me what I didn’t make clear and I’ll try to clear it up.

5 Likes

I still dont understand what is problem with this code.
When i console.log that out that works perfectly state.login is set to true …
Even after i use this assign func code still not working.

I’ll need to see your code to know exactly where you’re going wrong. But before you do, look into this:

The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.

Syntax:
Object.assign(target, …sources)
Object.assign() - JavaScript | MDN

Object.assign returns the leftmost object. So if you’re passing state as the first argument, then you will still mutate state. Instead, you should merge into a new object.

Make sure your target object is {}

If this is not it, then post your code and I’ll look it over

1 Like

Why is there no need to dispatch the action to the store?

because the tests will call dispatch with your action.

Calling the function loginAction should return an object with type property set to the string LOGIN.

@harisNT, I know it’s been a while, but I had the same problem until I figured it out. The relevant line in the description is this one:

Redux does not enforce state immutability, however, you are responsible for enforcing it in the code of your reducer functions.

So you can directly mutate the state, but you aren’t supposed to. That’s why your console.log() showed login: true but you were failing that test; freeCodeCamp’s test insists that you don’t mutate the original login value, but Redux will allow you to do it.

you are mutating the state object by doing “state.login = true” in the reducer function.All you need to do is: if(action.type == ‘LOGIN’){
return { login: true };
}
return state;

2 Likes

Try this.Works for me:

const defaultState = {
login: false
};

const reducer = (state = defaultState, action) => {
// change code below this line
if(action.type === ‘LOGIN’){
return {
login: true
}
}
return state
// change code above this line
};

const store = Redux.createStore(reducer);

const loginAction = () => {
return {
type: ‘LOGIN’
}
};

4 Likes

const defaultState = {
login: false
};

const reducer = (state = defaultState, action) => {
// change code below this line
switch(action.type){
case ‘LOGIN’:
state = Object.assign({},…state, {login : true})
break;

}
return state;
// change code above this line
};

const store = Redux.createStore(reducer);

const loginAction = () => {
return {
type: ‘LOGIN’
}
};

Why is this not working?
Reference is from Redux - Reducer

const defaultState = {
  login: false
};

const reducer = (state = defaultState, action) => {
  // change code below this line
  switch(action.type) {
    case 'LOGIN':
      return Object.assign({}, state, {
        login: true
      });
    defualt:
      return state;
  }
  // change code above this line
};

const store = Redux.createStore(reducer);

const loginAction = () => {
  return {
    type: 'LOGIN'
  }
};

I understand most of the codes above work, I think clearly returning a state object rather than an anonymous object with a ‘login’ property isn’t so clear.

const reducer = (state = defaultState, action) => {
  // change code below this line
  if(action.type == "LOGIN"){
    return **state =** {
            login: true
           }
    }   
    return state
  // change code above this line
};

I am in your state. I have no idea why when I cloned the state object and return the new object with login set to true does not work but returning {type: true} works? Below code does not pass the test. I was wondering if spread operator works in the code editor at all?

const defaultState = {
  login: false
};

const reducer = (state = defaultState, action) => {
  if (action.type === "LOGIN"){
    const newstate = {...state};  // I did not mutate the state object 
    newstate.login = true;
    return newstate;
  }
  return state
};

const store = Redux.createStore(reducer);

const loginAction = () => {
  return {
    type: 'LOGIN'
  }
};

```

It’s work for me. in the reducer you do not mutate the state, just create new one of object if you have some conditional if/else.

const defaultState = {
  login: false
};

const reducer = (state = defaultState, action) => {
  // change code below this line
  console.log(action);
  if (action.type === 'LOGIN') {
    return {
      login: true,
    }
  }
  return state;
  // change code above this line
};

const store = Redux.createStore(reducer);

const loginAction = () => {
  return {
    type: 'LOGIN',
  }
};