[譯] 使用 Go 和 ReactJS 構建聊天系統 (三)

本節完整代碼:GitHubcss

本文是關於使用 ReactJS 和 Go 構建聊天應用程序的系列文章的第 3 部分。你能夠在這裏找到第 2 部分 - 後端實現html

Header 組件

咱們先來建立一個很是簡單的 Header 組件。咱們須要在 frontend/src/ 目錄下 建立一個叫 components/ 的新目錄,並在其中添加一個 Header/ 目錄,它將容納 Header 組件的全部文件。前端

- src/
- - components/
- - - Header/
- - - - Header.jsx
- - - - index.js
- - - - Header.scss
複製代碼

注意 - 每當咱們建立一個新組件時,咱們將在 components/ 目錄中建立一個新目錄,咱們會在該目錄中建立這三個文件(.jsx,.js,*.scss)。node

Header.jsx

咱們須要在 Header.jsx 文件中實現函數組件。這將用於呈現網站的標題:react

import React from "react";
import "./Header.scss";

const Header = () => (
  <div className="header"> <h2>Realtime Chat App</h2> </div>
);

export default Header;
複製代碼

Header.scss

接下來,咱們須要加上一些樣式。 因爲 ReactJS 項目沒有處理 scss 文件的能力,所以咱們首先須要在 frontend/ 目錄中運行如下命令來安裝 node-sassgit

$ yarn add node-sass
複製代碼

安裝完成後,咱們就能夠添加樣式了:github

.header {
  background-color: #15223b;
  width: 100%;
  margin: 0;
  padding: 10px;
  color: white;

  h2 {
    margin: 0;
    padding: 0;
  }
}
複製代碼

index.js

最後,咱們要導出 Header 組件以致於其餘組件能夠導入它並在它們本身的 render() 函數中展現它:golang

import Header from "./header.jsx";

export default Header;
複製代碼

更新 App.js

如今已經建立好了 Header 組件,咱們須要將它導入 App.js,而後經過將它添加到咱們的 render() 函數中來展現它,以下所示:shell

// App.js
// 從相對路徑導入組件
import Header from './components/Header/Header';
// ...
render() {
  return (
    <div className="App"> <Header /> <button onClick={this.send}>Hit</button> </div>
  );
}
複製代碼

保存這個文件後,咱們的前端應用程序須要從新編譯,而後能夠看到 Header 組件成功展現在瀏覽器頁面的頂部。後端

恭喜 - 你已經成功建立了第一個 React 組件!

歷史聊天記錄組件

咱們已經構建並渲染了一個很是簡單的組件,因此咱們再來構建一個更復雜一點的組件。

在這個小節中,咱們將建立一個歷史聊天記錄組件,它用來顯示咱們從 WebSocket 服務收到的全部消息。

咱們將在 components/ 目錄中建立一個新文件夾叫 ChatHistory/。一樣,咱們須要爲這個組件建立三個文件。

ChatHistory.jsx

咱們從 ChatHistory.jsx 文件開始吧。它比以前的要稍微複雜一些,由於咱們將構建一個 Class 組件,而不是咱們上面 Header 組件的 Function 組件。

注意 - 咱們可使用 ES6 calss 定義類組件。若是你想了解更多有關信息,建議查看官方文檔:功能和類組件

在這個組件中,你會注意到有一個 render() 函數。 render() 函數返回一個用於展現此特定組件的 jsx

該組件將經過 props 從 App.js 函數中接收一組聊天消息,而後將它們按列表由上往下展現。

import React, { Component } from "react";
import "./ChatHistory.scss";

class ChatHistory extends Component {
  render() {
    const messages = this.props.chatHistory.map((msg, index) => (
      <p key={index}>{msg.data}</p>
    ));

    return (
      <div className="ChatHistory"> <h2>Chat History</h2> {messages} </div>
    );
  }
}

export default ChatHistory;
複製代碼

ChatHistory.scss

咱們在 ChatHistory.scss 中來爲 ChatHistory 組件添加一個小樣式,只是簡單的修改一下背景顏色和填充及邊距:

.ChatHistory {
  background-color: #f7f7f7;
  margin: 0;
  padding: 20px;
  h2 {
    margin: 0;
    padding: 0;
  }
}
複製代碼

Index.js

最後,咱們須要導出新組件,就像使用 Header 組件同樣,這樣它就能夠在 App.js 中被導入並展現:

import ChatHistory from "./ChatHistory.jsx";

export default ChatHistory;
複製代碼

更新 App.js 和 api/index.js

如今咱們又添加了 ChatHistory 組件,咱們須要實際提供一些消息。

在本系列的前一部分中,咱們創建了雙向通訊,回顯發送給它的任何內容,所以每當咱們點擊應用程序中的發送消息按鈕時,都會收到一個新消息。

來更新一下 api/index.js 文件和 connect() 函數,以便它從 WebSocket 鏈接收到新消息時用於回調:

let connect = cb => {
  console.log("connecting");

  socket.onopen = () => {
    console.log("Successfully Connected");
  };

  socket.onmessage = msg => {
    console.log(msg);
    cb(msg);
  };

  socket.onclose = event => {
    console.log("Socket Closed Connection: ", event);
  };

  socket.onerror = error => {
    console.log("Socket Error: ", error);
  };
};
複製代碼

所以,咱們在函數中添加了一個 cb 參數。每當咱們收到消息時,都會在第 10 行調用此 cb 會調函數。

當咱們完成這些修改,就能夠經過 App.js 來添加此回調函數,並在獲取新消息時使用 setState 來更新狀態。

咱們將把 constructor 函數 connect() 移動到 componentDidMount() 函數中調用,該函數將做爲組件生命週期的一部分自動調用(譯者注:在 render() 方法以後調用)。

// App.js
  componentDidMount() {
    connect((msg) => {
      console.log("New Message")
      this.setState(prevState => ({
        chatHistory: [...this.state.chatHistory, msg]
      }))
      console.log(this.state);
    });
  }
複製代碼

而後更新 App.jsrender() 函數並展現 ChatHistory 組件:

render() {
  return (
    <div className="App"> <Header /> <ChatHistory chatHistory={this.state.chatHistory} /> <button onClick={this.send}>Hit</button> </div> ); } 複製代碼

當咱們編譯並運行前端和後端項目時,能夠看到每當點擊前端的發送消息按鈕時,它會繼續經過 WebSocket 鏈接向後端發送消息,而後後端將其回傳給前端,最終在 ChatHistory 組件中成功展現!

總結

咱們成功地改進了前端應用程序,並將其視爲聊天應用程序。在本系列的下一部分中,將重點關注如下內容:

  • 改進前端:添加新的發送消息組件以容許咱們發送自定義消息
  • 改進後端:處理多個客戶端以及跨客戶端的通訊。

下一節:Part 4 - 處理多客戶端


原文:tutorialedge.net/projects/ch…

做者:Elliot Forbes 譯者:咔嘰咔嘰 校對:polaris1119

本文由 GCTT 原創編譯,Go 中文網 榮譽推出

相關文章
相關標籤/搜索