React and Redux: Extract State Logic to Redux

I am working on the React and Redux challenges. On the third challenge ‘extract state logic to redux’ I am stuck. I realize it is just basic redux but I am not able to solve it. My code is as follows:

// define ADD, addMessage(), messageReducer(), and store here:
const ADD = 'ADD';
const defaultState = {
  messages: []
};

function addMessage(msg) {
  return {
    type: ADD,
    message: msg
  };
};

const messageReducer = (state = defaultState, action) => {
  switch (action.type) {
    case ADD:
      var newState = {
        messages: state.messages.concat(action.message)
      };
      console.log(newState);
      return newState;
      break;
    default:
      return state
  };
  
};

const store = Redux.createStore(messageReducer);

I am failing on the ‘The store should exist and have an initial state set to an empty array.’ and ‘Dispatching addMessage against the store should immutably add a new message to the array of messages held in state.’ tests. I added a lot of console logs not shown here and I can clearly see that when the tests are run the state object is updated with the new message in the messages array. Any hints will be showered with thank yous.

1 Like

Hi biko-the-bird,

The 1st challenge is: “The initial state should equal an empty array”. In your code the initial state is set to an object and both methods return objects.

I’m guessing you’re failing test 4 and 6. Can you confirm this?

1 Like

Hi pwkrz,
I was failing tests 4 and 5. 6 passes. You were correct though my issue was solved by returning an array instead of a object. Thank you very much for responding so promptly

1 Like

You state in Reducer should be set to defaultState.messages so your state is empty array. And in case of ADD write return […state, action.message]. I hope this will help you.

It’s good code, but you didn’t follow the instructions quite right. The initial state should just be an empty array and not an object. It’s a case of overthinking things. Fix that and the reducer code and it should work for you.

Hi @biko-the-bird . Your code is fine but with slight mistakes . First thing is you need to pass the array to the reducer and not the entire object. Second this is in the reducer. In case ADD instead of creating an entire new object of state and returning that. Just append the message and return that itself. Below is the code without any errors and changes bolded :slightly_smiling_face:

const ADD = ‘ADD’;
const defaultState = {
messages: []
};

function addMessage(msg) {
return {
type: ADD,
message: msg
};
};

const messageReducer = (state = defaultState.messages, action) => {
switch (action.type) {
case ADD:
return […state, action.message];
break;
default:
return state;
};

};
const store = Redux.createStore(messageReducer);

2 Likes

hello, sorry to interrupt but can you explain this return […state, action.message]; to me? :frowning:

its like returning an array [] with a copy of state object on the first index and the message on the second index? It’s something like that? bcause not making any sense for me.

Thanks

Hi, (…) spread Operator serves to clone objects and not modify the original objects directly. So, in this example, you want to save the current message into a new state-array. Step by step:

  1. clone the state array: …state
  2. include the new message by action: action.message
1 Like

// This works for me.

const ADD = ‘ADD’;
const addMessage = (message) =>{
return{
type: ADD,
message:message
}
}

const messageReducer = (state = [], action) => {
switch(action.type){
case ADD:
return […state, action.message];
default:
return state;
}

};

const store = Redux.createStore(messageReducer);

2 Likes

can anybody help me out here. my code is running but i just wanted to ask why we are not calling this
store.dispatch(addMessage(‘My Name is Usama’));