This.state.messages.map is not a function in React Redux Help

This.state.messages.map is not a function in React Redux Help
0

#1

Tell us what’s happening:

I keep getting this error that “this.state.messages.map is not a function”

can anyone help me what is wrong with my code?

Your code so far


class DisplayMessages extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: '',
      messages: [],
    }

    this.handleChange = this.handleChange.bind(this);
    this.submitMessage = this.submitMessage.bind(this);
  }
  // add handleChange() and submitMessage() methods here

    handleChange(e) {
        this.setState({
          input: e.target.value
        })
    }

    submitMessage(e){
      e.preventDefault();
        this.setState({
          messages: this.state.messages.push(this.state.input),
          input: '',
        })
    }

  render() {
    return (
      <div>
        <h2>Type in a new Message:</h2>


        <input type='text' 
        onChange={this.handleChange} 
        value={this.state.input}  />

        <button onClick={this.submitMessage}> 
           Add message
        </button>
        <ul>
           {
             this.state.messages.map( (msg) => (
               <li> {msg} </li>
             )
             )
           }
        </ul>
        
      </div>
    );
  }
};

Your browser information:

User Agent is: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/front-end-libraries/react-and-redux/manage-state-locally-first


#2

The problem is how you are setting the value of messages in this.setState. You have forgotten what the push method returns as a value.


#3

Array.push() returns:

the new length property of the object upon which the method was called.

This is from the MDN documentation. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push

However, this is the less serious of mistakes that you’re making in your code. The more serious mistake is that you’re modifying state directly with your this.state.messages.push() call. This mutates this.state.messages which is what we don’t want to do.

Instead, create a copy of this.state.messages, push the input onto the copy, and set this.state.messages to said copy:

submitMessage(e){
  e.preventDefault();
  const messagesCopy = this.state.messages.slice();
  messagesCopy.push(this.state.input);
  this.setState({
    messages: messagesCopy,
    input: '',
  });
}

Good luck!


#4

As @WebDevCoach points out above, you could go the route of creating a copy and then pushing the the input property value into the copy, and then assigning the copy to message.

OR

Simply learn how you could use Array.prorotype.concat in your solution.


#5

After reading the MDN documentation and your example, I understand it now. Thank you!
.push returns the length and not the added element at the end. Also, thank you for pointing out that I am modifying state directly. I will use .concat method instead as randelDawson said.