Redux / React class a bit... buggy?

Redux / React class a bit... buggy?
0.0 0

#1

Hey y’all.

I just wanted to see if anyone else is having the problem of console.log not logging properly for them either, and the console giving you errors saying that they don’t recognize certain characters or don’t see your text you wrote properly?

Let me know when you can please.


#2

Example please? It’s hard to diagnose this without it.


#4
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();
    console.log("Lalalala");
    document.getElementsByTagName("input").value = '';
  }

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

          </ul>
        { /* change code above this line */ }
      </div>
    );
  }
};

For some reason, onSubmit doesn’t log this. The e.prevent works which is nice, but it won’t log anything. In addition, I can’t get passed this lesson. This is the second part of the Redux React course.

I reposted since I wasn’t sure if you got the reply.


#5

Well, there are some problems with your code.

I would not use a form here. I think of those has being used to submit data to a server.

        <form onSubmit={ this.submitMessage }>
          <input onChange={this.handleChange} value={this.state.input}/>
          <button>Add message</button>
        </form>

There is no need for that. Maybe there is a way to make it work, but I’m too tired to figure it out right now. I would just use that button and put a click handler on it. That’s much easier and more direct.

In your submitMessage:

  submitMessage(e) {
    e.preventDefault();
    console.log("Lalalala");
    document.getElementsByTagName("input").value = '';
  }

I don’t know if the preventDefault is necessary - I didn’t use it. But it doesn’t matter because your code is never getting here. Now that it (hopefully) is, what are you accessing the DOM. The whole point of React is that you NEVER access the DOM directly. Period. You have that data stored in state. Copy it from state (without mutating state) and add the new message and the put the new array into state.

Then you just need to add the JSX that outputs the list.


#6

OK, so I guess the form can work too:

        <form onSubmit={this.submitMessage}>
          <input onChange={this.handleChange} value={this.state.input}/>
          <button type="submit">submit</button>
        </form>

But then I’m running into of the issue of it trying to open a new tab, so the preventDefault comes in handy then.


#7

I got it to work this way, but I am pretty sure there is a more efficient way to set state for messages. Any ideas?

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) {
    var newArray = this.state.messages.slice();    
    newArray.push(this.state.input);   
    this.setState({messages:newArray})
    this.setState({input: ""});
  }

  render() {
    var stuff = this.state.messages.map((msg) => {
      return (<li key={msg}>{msg}</li>)
    })

    return (
      <div>
        <h2>Type in a new Message:</h2>
        { /* render an input, button, and ul here */ }
          <input onChange={this.handleChange} value={this.state.input}/>
          <button onClick={this.submitMessage}>Add message</button>
          <ul>
            {stuff}
          </ul>
        { /* change code above this line */ }
      </div>
    );
  }
};

#8

Wait. Better way to set state for array.

this.setState({messages: this.state.messages.concat([this.state.input])})


#9

No, concat merges arrays. Why create an array just to use the function?

A more concise way to do it would be:

   this.setState({
     messages: [...this.state.messages, this.state.input],
     input: ''
   })