[译] 使用 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 中文网 荣誉推出

相关文章
相关标签/搜索