Manage State locally first-

Tell us what’s happening:
Really at loss for what’s wrong here. The app is working fine (populating list with text that I input, and when I log the input from state to the console, you can see it’s there. However, this is only passing the first two tests. Any thoughts?

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.currentTarget.value
    })
  }
  submitMessage(){
    this.setState( ({ messages }) => ({messages: [...messages,          this.state.input]}))

    this.setState({
      input: ''
    })
  }

  render() {
    return (
      <div>
        <h2>Type in a new Message:</h2>
        { /* render an input, button, and ul here */ }
          <input 
          type="text" 
          value={this.state.input} 
          onChange={this.handleChange}>
          </input>

          <button 
          type="button" 
          onClick={this.submitMessage}>
          </button>

          <ul>
          {this.state.messages.map(item=> (
                <li>
                  {item}
                </li>
            ))}
          </ul>
        { /* change code above this line */ }
      </div>
    );
  }
};

Your browser information:

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

Link to the challenge:

React.js is asynchronous. Avoid to change state in more than one order. Then:

submitMessage(){
    this.setState({
      messages: this.state.messages.concat(this.state.input), // your code line with destructuring works also
      input:''
    });
  }

Look this:

State Updates May Be Asynchronous

React may batch multiple setState() calls into a single update for performance.

Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.

1 Like

Try using e.target.value instead

I found something in your code that I don’t understand. I tried it and only changed the handleChange function. The change was from e.currentTarget.value to e.target.value. And that caused it to pass all the tests.

Will you try that and see if it works for you? I’m very curious.
Thanks!

Why does that fix it? Just curious.

Yes, It does for me.

I know, but I don’t know why, do you?

Not really sure, maybe it’s just the test. Also, it’s what the React docs use.

Do note that even though they log the same thing in this case, they are not really the same.

currentTarget

Identifies the current target for the event, as the event traverses the DOM. It always refers to the element to which the event handler has been attached, as opposed to event.target which identifies the element on which the event occurred.

target

A reference to the object that dispatched the event. It is different from event.currentTarget when the event handler is called during the bubbling or capturing phase of the event.

yes thank you very much. I see the other posts explaining why this is

I might be wrong, I don’t really know that much about enzyme but it looks like the simulate is using a mock event object with target being the property. Again, it’s just speculation based on 5 minutes of looking into it.

NOTE: there are spoilers in this link to the test

Summary

manage-state-locally-first.english.md

simulate(''change'', { target: { value: }v })

Thanks for that. You’re right, they are simulating using only target. I appreciate you finding this.
So iThompkins original code was perfectly fine in that there was no reason not to use currentTarget (no reason to be aware of events being picked up during capturing or bubbling phases).