React Chat Bot - Ways to improve my code?

React Chat Bot - Ways to improve my code?
0

#1

I am trying to do a chat bot, I am fine with the UI now and I think it’s arrived the moment to improve my code which was made by me using my poor knowledge.

The component loads a JSON file which contains basically some messages before sending any.

I’ve used TransitionGroup but it’s not doing much but I like how keeps things a little bit more in order.
As you can see the json file is set as a state and it’s updated when the data is submitted from the input field.

Each time a user types something, what it is typed is pushed into the object including also the time and that the message was sent by a human. For the id I think things are a little bit trickier because the id is actually the message being sent with the current time (So I don’t think it’s a good way to give ids to the divs, especially because I can’t type the same message twice before it has passed at least one minute).

I tried to change it to a random number but it didn’t work for some reason (well, I think I’ve done something wrong because it keeps adding new element during the render).

scroll to bottom, the other functions below that and that ref thing are all related to the animation to keep the chat section scrolled to the bottom when a new message is submitted.

This is the code I am trying to improve:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import Chat from './chat.json';
import './Messages.css';
import { TransitionGroup } from 'react-transition-group' // ES6

class ChatBot extends React.Component {
 constructor(props) {
  super(props);
   this.state = {
  input:'',
  chat:Chat,
  };
 } 


    handleClick(event) {
    let newObj= [...this.state.chat];
    let current_time = new Date(); // for now
    let time=current_time.getHours()+":"+(current_time.getMinutes()<10?'0':'')+current_time.getMinutes();

    this.setState({ input: '' });  
    /*when the message is not only spaces*/
    newObj.push({"id":"human","text":this.state.input,"time":time});
    this.setState({chat: newObj});  

  }

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

  _handleKeyPress = (e) => {
    if (e.key === 'Enter') {
  this.handleClick()
    }
  }

scrollToBottom = () => {
  this.messagesEnd.scrollIntoView({ behavior: "smooth" });
}

componentDidMount() {
  this.scrollToBottom();
}

componentDidUpdate() {
  this.scrollToBottom();
}

  render() {
    const deg=45;
  const style_1 = { 
        transform: `rotate(${deg}deg)`
    };

  let items=Object.keys(this.state.chat).map((key, i) => {
  let key_each=this.state.chat[key].text+this.state.chat[key].time;
    let current_time = new Date(); // for now
    let time=current_time.getHours()+":"+(current_time.getMinutes()<10?'0':'')+current_time.getMinutes();

//  console.log(key_each);
  return ( 
    <div key={key_each}>
    {this.state.chat[key].id==="human"? 
    (<div>
    <div className="from-me">
      <p>{this.state.chat[key].text}
  <span class="metadata">
  <span class="time">{this.state.chat[key].time===time?"just now":this.state.chat[key].time}</span>
  </span>
  </p>

    </div>
    </div>):
    (<div key={key_each}>
    <div className="from-them">
      <p>{this.state.chat[key].text}
      <span class="metadata">
  <span class="time">{this.state.chat[key].time===time?"just now":this.state.chat[key].time}</span>
  </span>
  </p>
    </div>
    </div>)} 
    </div>
    );
});
    return (

<div className="Messages">


          <section>

       <TransitionGroup>
                {items}
       </TransitionGroup>
     
        <div style={{ float:"left", clear: "both" }}
             ref={(el) => { this.messagesEnd = el; }}>
        </div>


          </section>

           <div className="input-group">
                    <input type="text" class="form-control" value={this.state.input} onChange={this.handleChange.bind(this)} onKeyPress={this._handleKeyPress} placeholder="Type Something..."/>
                    <span className="input-group-addon" onClick={this.handleClick.bind(this)}><i class="fas fa-location-arrow" style={style_1}></i></span>
                </div>
        </div>

   );
  }
}
  export default ChatBot;

#2

it seems you need a unique identifier of some sort so people can send duplicate messages. Since you are using js date already, you could use getSeconds() or even getMilliseconds() but this probably isn’t the best solution


#3

Thanks, it worked
Alright but at this point I wonder if I should rewrite the code because what I am doing doesn’t make sense I am only adding complexity to it when not needed.


#4

I would make the unique identifier for each message to just be a simple count variable.

Then you can just count++ every time a new message is posted