本節完整程式碼:GitHub
本文是關於使用 ReactJS 和 Go 構建聊天應用程式的系列文章的第 3 部分。你可以在這裡找到第 2 部分 - 後端實現
Header 元件
我們先來建立一個非常簡單的 Header 元件。我們需要在 frontend/src/
目錄下 建立一個叫 components/
的新目錄,並在其中新增一個 Header/
目錄,它將容納 Header 元件的所有檔案。
- src/
- - components/
- - - Header/
- - - - Header.jsx
- - - - index.js
- - - - Header.scss
複製程式碼
注意 - 每當我們建立一個新元件時,我們將在
components/
目錄中建立一個新目錄,我們會在該目錄中建立這三個檔案(.jsx,.js,*.scss)。
Header.jsx
我們需要在 Header.jsx
檔案中實現函式元件。這將用於呈現網站的標題:
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-sass
:
$ yarn add node-sass
複製程式碼
安裝完成後,我們就可以新增樣式了:
.header {
background-color: #15223b;
width: 100%;
margin: 0;
padding: 10px;
color: white;
h2 {
margin: 0;
padding: 0;
}
}
複製程式碼
index.js
最後,我們要匯出 Header
元件以至於其他元件可以匯入它並在它們自己的 render()
函式中展示它:
import Header from "./header.jsx";
export default Header;
複製程式碼
更新 App.js
現在已經建立好了 Header
元件,我們需要將它匯入 App.js
,然後通過將它新增到我們的 render()
函式中來展示它,如下所示:
// 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.js
的 render()
函式並展示 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