Naučte se ReactJs vytvořením chatovacího rozhraní

Vytvoření chatovací aplikace od nuly pomocí ReactJs

Co je ReactJS?

Jednoduše řečeno, HTML + JS + CSS =React

Proč ReactJS?

  1. Nedávno jsem se přesunul do role, kde dělám celý backend s Pythonem. I když to preferuji, nechci, aby mé dovednosti JS vyšly nazmar.
  2. Většina mých přátel jsou front-end vývojáři, takže je trochu pod tlakem vrstevníků znát jejich jazyk (jak z hlediska Reactu, tak toho, co mluví).
  3. Chtěl jsem vytvořit svůj vlastní web s portfoliem pomocí Gatsby, který je vytvořen pomocí React.
  4. Bonus:Vývojář frontendu, se kterým pracuji, nemůže jen říct:„to nelze udělat v reakci“ a odejít tak.

Předpoklady

Musíte rozumět front-endovým technologiím, jako jsou HTML, CSS a JS. Nemusíte je ovládat všechny. Pokud víte, jak je spojit a vytvořit webovou stránku, můžete začít.

ReactJs — Základní porozumění

React = Component + props + state

Tři základní terminologie, se kterými se jako začátečník setkáte, jsou komponenta, stav a rekvizity. Kromě toho slyším vymyšlená jména jako „Lazy React“, „Háčky reakce“ atd., které jsou v mém seznamu, ale ne v tomto blogu.

Kde začít?

Jsem dokumentační šílenec. S dokumentací trávím šíleně mnoho času a další zdroje/návody hledám, jen když to nefunguje.

Dokumentační tutoriál React vás provede hrou tic tac toe a naučí vás, jak organizovat vaše komponenty a hrát si s jejími stavy a rekvizitami. I když jsem dokončil tutoriál, neměl jsem ponětí, jak jej aplikovat na můj projekt.

Co pro mě nakonec fungovalo, bylo myšlení v reakci. Učí vás rozdělením komponent webové stránky a jak do nich zasahovat stavy a rekvizity.

Na tomto tutoriálu je skvělé, že se velmi blíží realitě. Front-end vývojář bude mít vždy návrh, se kterým bude pracovat. Takže začít React s prázdným listem jako v Tic Tac Toe moc nepomohlo.

Co stavíme?

Měl jsem tento společný front-end modul chatu vytvořený pomocí prostého HTML, CSS a JS. Byla to moje šablona pro vytváření chatbotů a hraní si s nimi. Většina mých hobby projektů chatbotů má tento front-end.

Mým konečným cílem bylo dosáhnout frontendu chatu, který by posílal a přijímal zprávy do backendového API. Můžete přímo skákat a hrát si s kódem v mém úložišti GitHub.

Myšlení v komponentách

Prvním krokem pro začátek je definování jednotlivých komponent uživatelského rozhraní. Co tím myslíte, že se můžete ptát?

Na obrázku výše vidíme asi 4–5 prvků uživatelského rozhraní. Ty jsou zabaleny do jednotlivých entit nazývaných komponenty.

Tlačítko Odeslat


class SendButton extends Component{
    render(){
      return (
         <div className="send\_message" 
              <div className="text">send</div>
         </div>);
    }
}

Textové pole


class MessageTextBoxContainer extends Component{
  render(){
    return(
      <div className="message\_input\_wrapper">
        <input id="msg\_input" 
               className="message\_input" 
               placeholder="Type your messages here..."/> 
      </div>
    );
  }
}

Avatar

Avatar je místo, kam jde profilový obrázek dané osoby. Prozatím zůstaneme u různých pozadí.

class Avatar extends Component {
  render(){
    return(
      <div className="avatar"/>
    );
  }
}

Zpráva

Komponenta MessageBox obsahuje komponentu Avatar. Pro každou zprávu pouze projdeme a vytvoříme N těchto komponent.


class MessageBox extends Component{
  render(){
    return(
      <li className={`message ${this.props.appearance} appeared`}>
        <Avatar></Avatar>
        <div className="text\_wrapper">
            <div className="text">{this.props.message}</div>
        </div>
      </li>
    );
  }
}

Celá aplikace

Podobně spojíme celé uživatelské rozhraní spojením těchto komponent dohromady. Má MessageContainer, kde jsou uvedeny zprávy, TextBox a SendButton. Prozatím ignorujte this.state nebo this.handleClick

class ChatApp extends Component {
render() {
    return (
      <div className="chat\_window">
        < **MessagesContainer** messages={this.state.messages}/>
        <div className="bottom\_wrapper clearfix">
          < **MessageTextBoxContainer/** >
          < **SendButton** handleClick={this.handleClick}/>
        </div>
      </div>
    );
  }
}

Zachycení události

Než budeme pokračovat v narážení na stavy a rekvizity komponenty, podívejme se, jaké události musíme zvládnout.

  1. Send_message při stisknutí tlačítka Odeslat.
  2. Odeslat zprávu po stisknutí klávesy Enter.

V tomto bloku prozkoumáme, jak zachytit událost press_enter a send_button_click

Vraťme se k naší komponentě SendButton a připojte metodu pro zpracování kliknutí. Podobně můžeme do textového pole přidat událost onKeyPress a zachytit události.

class SendButton extends Component{
**handleClick(){  
        console.log("I am captured");  
    }**  

render(){
      return (
         <div className="send\_message" 
**onClick={this.props.handleClick}>**
              <div className="text">send</div>
         </div>);
    }
}

Zpracování událostí

Nyní, když jsme zachytili události kliknutí na tlačítko a stisknutí klávesy. Podívejme se, jak se s těmito událostmi vypořádat. Toto je část, se kterou jsem měl největší problémy.

Po kliknutí na odeslat nebo po stisknutí klávesy Enter se aktuální zpráva zobrazí Textové pole by mělo být přidáno jako MessageComponent to Komponenta MessageContainer.

Nyní si projdeme každou z těchto komponent a uvidíme, jaká jsou data, která potřebujeme k naplnění požadovaných informací. Tato data jsou definována stavem a podpěrami komponenty.

Odvození stavů a ​​rekvizit

Podívejme se na jednotlivé komponenty a podívejme se, jaká data potřebuje, aby dobře plnila svou práci.

  1. SendButton — Potřebuje přístup k aktuální_zprávě, kterou uživatel píše, aby ji mohl odeslat chatbotovi.
  2. MessageTextBox — Potřebuje udržovat a aktualizovat current_message, když ji uživatel napíše (stav) a odešle ji chatbotovi po stisknutí klávesy enter
  3. MessageContainer —  Potřebuje udržovat seznam všech zpráv od robota i uživatele, aby jej naplnil.

Abychom mohli naplnit aktuální zprávu v MessageContainer, potřebujeme znát aktuální zprávu, kterou uživatel zadal do MessageTextBox .

MessageContainer také potřebuje sledovat všechny zprávy, které byly dosud napsány/přijaty. proto by měl jako vlastnost pole zpráv.

class TextBox extends Component{

constructor(props){
    this.state.current\_message = ""
}

**onChange(e) {  
    this.setState({  
      current\_message: e.target.value;      
    });   
    if(e.key === "Enter"){  
      // We need to add a new message to MessageContainer component  
    }**  

**}**
render(){
    return(
      <div className="message\_input\_wrapper">
        <input ... 
             value={this.props.current\_message} 
             onChange={this.props.onChange}/>
      </div>
    );
  }
}

Nyní můžete vidět, že zpočátku je current_message prázdný řetězec a onChange, když zadáváme text do naší komponenty TextBox. Ale změny, které provedete v komponentě TextBox, nejsou viditelné pro MessageContainer

V Reactu je stav sdílení dosaženo jeho přesunem k nejbližšímu společnému předkovi komponent, které to potřebují. Tomu se říká „zvedání státu“.

Stav zvedání nahoru

Nyní přichází otázka, na kterou komponentu bychom měli přesunout ovládání? Nakreslíme jednoduchý strom komponent a uvidíme, kam se co hodí.

Když to nakreslíme, je docela zřejmé, že všechny podřízené komponenty potřebují přístup k current_message a seznamu zpráv, které už robot viděl. Naštěstí máme pouze jednu nadřazenou aplikaci ChatApp, která deleguje všechny požadavky na zpracování stavu a událostí na příslušné podřízené komponenty

Komponenta ChatApp bude právě teď trochu chaotická. Nejprve si nadefinujme všechny funkce, které potřebujeme, a později je připojme k událostem, jak je potřebujeme.

**addMessageBox** (enter=true){
  let messages = this.state.messages;
  let current\_message = this.state.current\_message;
  if(current\_message && enter){
    messages = [...messages, {"message":current\_message}];
}

**handleClick** (){
  this.addMessageBox();
}

**\_handleKeyPress** (e) {
  let enter\_pressed = false;
  if(e.key === "Enter"){
    enter\_pressed = true;
   }
   this.addMessageBox(enter\_pressed)
}

render() {
  return (
    <div className="chat\_window">
      <MessagesContainer messages={this.state.messages}/>
      <div className="bottom\_wrapper clearfix"> . 
       <**MessageTextBoxContainer   
           \_handleKeyPress={this.\_handleKeyPress}**   
           onChange={this.onChange}
           message={this.state.current\_message}> .      
       </MessageTextBoxContainer>

      <SendButton **handleClick={this.handleClick}/>**  
</div>
    </div>
);}

Jak vidíte ve úryvku, definujeme obslužné rutiny událostí a stav a rekvizity na úrovni nadřazené komponenty a delegujeme je na podřízené komponenty.

Od někoho, kdo nenáviděl frontend a Javascript, po někoho, kdo pomocí něj vytvořil ChatApp, věřte mi, že se mi JS skutečně líbí jen kvůli Reactu. Posuňme se kupředu, pokud mě uvidíš, jak buduji frontend, bude to s Reactem.