Event handlers, passing to unordered list

The event handlers might not be correct since the submit button does not return anything. What is the starting point to fix this?

class DisplayMessages extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: '',
      messages: []
    }
  this.handleChange = this.handleChange.bind(this);
  this.submitMessage = this.submitMessage(this);
  }
  // Add handleChange() and submitMessage() methods here
  handleChange(event)  {this.setState({input: event.target.value})}
  submitMessage() {
    this.setState({messages: this.state.messages.concat(this.state.input)
    });
  }
  render() {
    let listItems = messsages.map(item =>
    <li>{item}</li>
    );
    return (
      <div>
        <h2>Type in a new Message:</h2>
        { /* Render an input, button, and ul below this line */ }
        <input type="text" onChange={this.handleChange} />
        <button type="submit" value={this.submitMessage} onClick={this.submitMessage}>Add message</button>
        <ul>
        {listItems}
        </ul>
        { /* Change code above this line */ }
      </div>
    );
  }
};

Challege: Manage State Locally First
Learn React and Redux: Manage State Locally First | freeCodeCamp.org

Do you mean to bind the submitMessage function, as you have the handleChange? Look at those two lines, there’s something missing in the submitMessage binding.

Thanks, the binding is fixed.
this.submitMessage = this.submitMessage.bind(this);

There is no display and understanding the button element in render seems to be the problem that needs help. It has been hard to search for explanations on the value attribute in an input element. I do not know where the value attribute comes from, maybe event.target.value. The value attribute is then used in the input element with the event handler. Do both value and the event handler need to be in an input element?
The example is the first app.

const handleSubmit = e => {
    e.preventDefault();
    alert("you have searched for - " + value);
    // or you can send to backend
  };

return (
    <div className="App">
      <form>
        <input value={value} onChange={handleChange}/>
        <button onClick={handleSubmit} type="submit">
          Submit
        </button>
      </form>
    </div>
  );
}

How to trigger a button click on Enter in React | Reactgo

Clicking the button amends the state of messages. The button element could be passed this.input or this.submitMessage. This is confused.

<button type="submit" value={this.submitMessage} onClick={this.submitMessage}>Add message</button>

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(event)  {this.setState({input: event.target.value})}
  submitMessage() {
    this.setState({messages: this.state.messages.concat(this.state.input)
    });
  }
  render() {
    let listItems = messsages.map(item =>
    <li>{item}</li>
    );
    return (
      <div>
        <h2>Type in a new Message:</h2>
        { /* Render an input, button, and ul below this line */ }
        <input type="text" onChange={this.handleChange} />
        <button type="submit" value={this.submitMessage} onClick={this.submitMessage}>Add message</button>
        <ul>
        {listItems}
        </ul>
        { /* Change code above this line */ }
      </div>
    );
  }
};

Update
I am reading about input’s attribute of value.
https://forum.freecodecamp.org/t/react-and-redux-manage-state-locally-first-value-this-state-input/231891/3

The value questions are solved. Value is the input of an input element. An input element will take change from an event handler method and input from value.
This is the updated code that now does display something. The listing is being worked on.

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(event)  {this.setState({input: event.target.value})}
  submitMessage() {
    this.setState({input: "", messages: this.state.messages.concat(this.state.input)
    });
  }
  render() {
    // let listItems = messsages.map(item =>
    // <li>{item}</li>
    // );
    return (
      <div>
        <h2>Type in a new Message:</h2>
        { /* Render an input, button, and ul below this line */ }
        <input type="text" onChange={this.handleChange} value={this.input} />
        <button type="submit" onClick={this.submitMessage}>Add message</button>
        <ul />
        { /* Change code above this line */ }
      </div>
    );
  }
};

There is some local state reading to do. The input element does not take this.input but this.state.input.

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

Solution

//Manage state locally first 
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(event)  {this.setState({input: event.target.value})}
  submitMessage() {
    this.setState({input: "", messages: this.state.messages.concat(this.state.input)
    });
  }
  render() {
    return (
      <div>
        <h2>Type in a new Message:</h2>
        { /* Render an input, button, and ul below this line */ }
        <input type="text" onChange={this.handleChange} value={this.state.input} />
        <button type="submit" onClick={this.submitMessage}>Add message</button>
        <ul>
        {this.state.messages.map(element =>
        <li>{element}</li>)}
        </ul>
        { /* Change code above this line */ }
      </div>
    );
  }
};

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.