作者:叶毒手_938 | 来源:互联网 | 2023-09-15 15:03
在本节中,我们将着眼于改进前端并充实该应用程序,使其看起来像一个正规的在线聊天应用程序。本节完成后的效果如下:基于组件的方法在React以及所有其他流行的前端框架中,我们倾向于将应
在本节中,我们将着眼于改进前端并充实该应用程序,使其看起来像一个正规的在线聊天应用程序。
本节完成后的效果如下:
基于组件的方法
在 React 以及所有其他流行的前端框架中,我们倾向于将应用程序划分为一系列组件。 每个组件通常代表应用程序上的一个元素,例如我们应用程序内的用户列表或聊天记录部分。
这种基于组件的方法有很多优点,并且有效地允许较大的团队处理单个组件,而不必影响其他团队处理应用程序。这些组件为您提供了一定的 系统解耦,并且有效地允许您通过组合构建应用程序,并在逻辑上对目录结构进行分组。
头部组件
让我们从创建一个简单的 Header
组件开始。为此,我们将在 frontend/src/
目录下创建一个名为 components/
的目录,并在其中创建 Header/
目录,该目录将存放 Header 组件的所有文件。
- src/
- - components/
- - - Header/
- - - - Header.jsx
- - - - index.js
- - - - Header.scss
注意 - 未来,无论何时创建新组件,我们都会在 components/
目录中为其创建新目录,并且通常将在该目录中创建这三个文件。
Header.jsx
让我们在 Header.jsx
文件中实现我们的 function component
。这将为我们的网站提供一个简单的标题:
import React from "react";
import "./Header.scss";
const Header = () => (
Realtime Chat App
);
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 (
);
}
保存后,前端应用程序应重新编译,并且应该在浏览器页面顶部看到成功渲染新的 Header
组件。
恭喜 —— 您已经成功创建了第一个 React 组件!
聊天记录组件
好的,我们已经成功构建并渲染了一个非常简单的组件,让我们构建更多。
在本节中,我们将创建一个聊天记录组件,该组件将显示从 WebSocket 服务器收到的所有消息。
我们将再一次在 components/
目录中创建一个新文件夹,但是这次目录名为 ChatHistory/
。 创建此目录后,让我们为组件创建三个文件。
ChatHistory.jsx
让我们从 ChatHistory.jsx
文件开始。这次,它将变得稍微复杂些,因为我们将要构建一个 Class
组件,而不是上面用于 Header
组件的 Function
组件。
注意: 我们可以使用 ES6 class
来定义类组件。如果您想详细了解两者之间的差异,建议您在此处查看官方文档: Function 和 Class 组件
您会注意到在这个 Component
组件中有一个 render()
函数。render()
函数的作用是返回我们希望在应用程序中为该特定组件呈现的 jsx
。
该组件将从其 App.js
函数通过其 props
获取一个聊天消息数组,随后将它们相互呈现。
import React, { Component } from "react";
import "./ChatHistory.scss";
class ChatHistory extends Component {
render() {
const messages = this.props.chatHistory.map((msg, index) => (
{msg.data}
));
return (
Chat History
{messages}
);
}
}
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
组件,我们需要向它提供一些消息。
在本系列的前一部分中,我们建立了双向通信,以回显发送给它的所有内容,因此从技术上讲,每当我们在应用程序中点击 send message
按钮时,我们都会获得一个简单的新消息源。
让我们更新我们的 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
参数。每当我们收到消息时,就会在 line 10
调用此 cb
。
进行了这些更改后,无论何时收到新消息,我们都可以更新 App.js
以添加此回调函数并使用 setState
更新状态。
我们将把我们的 connect()
调用从 constructor
移到一个 componentDidMount()
函数中,该函数将在组件生命周期中被自动调用。
// App.js
componentDidMount() {
connect((msg) => {
console.log("New Message")
this.setState(prevState => ({
chatHistory: [...this.state.chatHistory, msg]
}))
console.log(this.state);
});
}
然后,我们要更新我们的 render()
函数并显示我们的 ChatHistory
组件:
render() {
return (
);
}
当我们编译并运行 frontend
和 backend
时,我们应该看到,只要我们点击前端上的 send message
按钮,它就会继续通过 WebSocket 连接向后端发送消息,然后我们的后端回显它返回到前端,并在我们的 ChatHistory
组件中成功渲染!
总结
本节,我们成功地改进了前端应用程序,并将其作为聊天应用程序一起使用。在下一节中,我们将重点关注以下内容:
- 改进前端以添加新的发送消息组件,以允许我们将自定义消息发送回服务器。
- 改进我们的后端以处理多个客户端和跨客户端通信。
本文译自tutorialedge