如何在 10 分钟内构建一个 React.js 聊天应用程序
在本文中,我将向您展示使用 React.js 创建聊天应用程序的最简单方法。它完全不需要服务器端代码,因为我们将让Chatkit API处理后端。
我假设你已经了解基本的 JavaScript 知识,并且之前接触过一些 React.js。除此之外,没有其他先决条件。
如果您按照本教程进行操作,您最终将获得您自己的聊天应用程序,然后您可以在此基础上进行进一步的构建。
让我们开始吧!
步骤 1:将 UI 分解为组件
React 是围绕组件构建的,因此创建应用程序时要做的第一件事就是将其 UI 分解为组件。
我们先画一个矩形框住整个应用。这是你的根组件,也是所有其他组件的共同祖先。我们把它命名为App
:
一旦定义了根组件,就需要问自己以下问题:
该组件有哪些直接子组件?
在我们的例子中,给它三个子组件是有意义的,我们将其称为以下内容:
Title
MessagesList
SendMessageForm
让我们为每个图形绘制一个矩形:
这为我们提供了应用程序背后的不同组件和架构的良好概述。
我们本可以继续思考这些组件又有哪些子组件。这样,我们就可以将 UI 拆分成更多组件,例如,将每条消息拆分成各自的组件。不过,为了简单起见,我们就此打住。
第 2 步:设置代码库
现在我们需要设置我们的代码库。我们将使用尽可能简单的结构:一个index.html文件,其中包含指向 JavaScript 文件和样式表的链接。我们还导入了 Chatkit SDK 和 Babel,用于转换我们的 JSX:
这是 Scrimba Playground,里面有本教程的最终代码。我建议你在新标签页中打开它,遇到问题时可以尝试一下。
或者,您可以将 Scrimba 项目下载为 .zip 文件并运行一个简单的服务器以在本地启动和运行它。
步骤 3:创建根组件
有了存储库,我们就可以开始编写一些 React 代码,我们将在index.js文件中执行此操作。
让我们从主组件开始App
。这将是我们唯一的“智能”组件,因为它将处理数据并与 API 建立连接。以下是它的基本设置(在添加任何逻辑之前):
class App extends React.Component {
render() {
return (
<div className="app">
<Title />
<MessageList />
<SendMessageForm />
</div>
)
}
}
正如您所见,它只是渲染出三个子项:<Title>
、<MessageList>
和<SendMessageForm>
组件。
不过,我们会让它更复杂一些,因为聊天消息需要存储在这个组件的状态App
中。这样我们就可以通过 访问消息this.state.messages
,并将它们传递给其他组件。
我们将首先使用虚拟数据,以便了解应用程序的数据流。然后,我们将稍后将其替换为来自 Chatkit API 的真实数据。
让我们创建一个DUMMY_DATA
变量:
const DUMMY_DATA = [
{
senderId: "perborgen",
text: "who'll win?"
},
{
senderId: "janedoe",
text: "who'll win?"
}
]
然后我们将这些数据添加到状态并将其作为 propApp
传递给组件。MessageList
class App extends React.Component {
constructor() {
super()
this.state = {
messages: DUMMY_DATA
}
}
render() {
return (
<div className="app">
<MessageList messages={this.state.messages} />
<SendMessageForm />
</div>
)
}
}
在这里,我们正在初始化中的状态,constructor
并且我们还将其传递this.state.messages
给MessageList
。
注意,我们
super()
在构造函数中调用。如果你想创建一个有状态的组件,就必须这样做。
步骤 4:渲染虚拟消息
让我们看看如何在组件中渲染这些消息MessageList
。如下所示:
class MessageList extends React.Component {
render() {
return (
<ul className="message-list">
{this.props.messages.map(message => {
return (
<li key={message.id}>
<div>
{message.senderId}
</div>
<div>
{message.text}
</div>
</li>
)
})}
</ul>
)
}
}
这是一个所谓的“愚蠢的组件”。它接受一个 prop,messages
其中包含一个对象数组。然后我们只需从对象中渲染出text
和属性即可。senderId
随着我们的虚拟数据流入该组件,它将呈现以下内容:
现在,我们已经完成了应用的基本结构,并且能够渲染消息了。太棒了!
现在让我们用聊天室的实际消息替换我们的虚拟数据!
步骤 5:从 Chatkit 获取 API 密钥
为了获取消息,我们需要连接 Chatkit API。当然,我们需要获取 API 密钥。
现在,我鼓励你按照我的步骤操作,以便你能够创建并运行自己的聊天应用程序。你可以使用我的Scrimba 游乐场来测试你自己的 API 密钥。
首先在这里创建一个免费帐户。完成后,您将看到您的仪表板。您可以在这里创建新的 Chatkit 实例。创建一个实例并为其指定您想要的名称:
然后,您将导航到新创建的实例。这里您需要复制四个值:
- 实例定位器
- 测试令牌提供者
- 房间号
- 用户名
我们将从实例定位器开始:
如果你向下滚动一点,你会发现测试令牌提供程序:
下一步是创建用户和房间,这在同一个页面上完成。请注意,您必须先创建用户,然后才能创建房间,这样您才能访问房间标识符。
现在你已经找到了你的四个标识符。干得好!
但是,在我们回到代码库之前,我希望您也从 Chatkit 仪表板手动发送一条消息,因为这将有助于我们完成下一章。
具体操作如下:
这样,我们实际上就可以在下一步中呈现一条消息。
步骤 6:渲染真实聊天消息
现在让我们回到我们的index.js文件并将这四个标识符作为变量存储在文件顶部。
以下是我的,但我鼓励您创建自己的:
const instanceLocator = "v1:us1:dfaf1e22-2d33-45c9-b4f8-31f634621d24"
const testToken = "https://us1.pusherplatform.io/services/chatkit_token_provider/v1/dfaf1e22-2d33-45c9-b4f8-31f634621d24/token"
const username = "perborgen"
const roomId = 9796712
一切就绪后,我们终于可以连接 Chatkit 了。这将在App
组件中实现,更具体地说是在componentDidMount
方法中。这就是将 React.js 组件连接到 API 时应该使用的方法。
首先,我们将创建一个chatManager
:
componentDidMount() {
const chatManager = new Chatkit.ChatManager({
instanceLocator: instanceLocator,
userId: username,
tokenProvider: new Chatkit.TokenProvider({
url: testToken
})
})
…然后我们将chatManager.connect()
连接 API:
chatManager.connect().then(currentUser => {
currentUser.subscribeToRoom({
roomId: **roomId**,
hooks: {
onNewMessage: message => {
this.setState({
messages: [...this.state.messages, message]
})
}
}
})
})
}
这使我们能够访问该currentUser
对象,它是与 API 交互的接口。
currentUser
注意:由于我们稍后需要使用,因此我们将通过执行以下操作将其存储在实例上this.currentUser = currentUser
。
然后,我们调用currentUser.subscribeToRoom()
并传递我们的roomId
钩子onNewMessage
。
每次有新消息广播到聊天室时,都会触发此onNewMessage
钩子。因此,每次触发时,我们只需将新消息添加到 的末尾即可this.state.messages
。
这会导致应用程序从 API 获取数据,然后将其呈现在页面上。
这太棒了,因为我们现在有了客户端-服务器连接的框架。
哇噢!
步骤 7:处理用户输入
接下来我们需要创建组件SendMessageForm
。这是一个所谓的受控组件,这意味着该组件通过其状态来控制在输入字段中渲染的内容。
看一下该render()
方法,并特别注意我突出显示的行:
class SendMessageForm extends React.Component {
render() {
return (
<form
className="send-message-form">
<input
**onChange={this.handleChange}
value={this.state.message}**
placeholder="Type your message and hit ENTER"
type="text" />
</form>
)
}
}
我们正在做两件事:
- 使用
onChange
事件监听器监听用户输入,以便我们可以触发handleChange
方法 - 使用以下方式明确设置
value
输入字段this.state.message
这两个步骤之间的联系可以在handleChange
方法内部找到。它只是将状态更新为用户在输入字段中输入的内容:
handleChange(e) {
this.setState({
message: e.target.value
})
}
这会触发重新渲染,并且由于输入字段是使用 从状态明确设置的value={this.state.message}
,因此输入字段将被更新。
因此,尽管当用户在输入字段中输入内容时,应用程序会感觉即时,但数据实际上是在 React 更新 UI 之前通过状态进行的。
为了实现这个功能,我们需要给组件一个constructor
。在其中,我们将初始化状态并this
在handleChange
方法中绑定:
constructor() {
super()
this.state = {
message: ''
}
this.handleChange = this.handleChange.bind(this)
}
我们需要绑定该handleChange
方法,以便能够访问this
其中的关键字。JavaScript 就是这样运作的:在函数体中,this
关键字默认为undefined 。
步骤 8:发送消息
我们的SendMessageForm
组件快完成了,但我们还需要处理表单提交。我们需要获取消息并发送出去!
为了做到这一点,我们将事件handleSubmit
处理程序与onSubmit
事件监听器连接起来<form>
。
render() {
return (
<form
**onSubmit={this.handleSubmit}**
className="send-message-form">
<input
onChange={this.handleChange}
value={this.state.message}
placeholder="Type your message and hit ENTER"
type="text" />
</form>
)
}
由于我们已经将输入字段的值存储在 中this.state.message
,因此在提交时传递正确的数据实际上非常容易。我们只需执行以下操作:
handleSubmit(e) {
e.preventDefault()
this.props.sendMessage(this.state.message)
this.setState({
message: ''
})
}
这里,我们调用sendMessage
prop 并将其作为参数传入this.state.message
。你可能会对此感到困惑,因为我们sendMessage
还没有创建方法。不过,我们会在下一节中创建它,因为该方法位于App
组件内部。所以不用担心!
其次,我们通过设置this.state.message
为空字符串来清除输入字段。
这是整个SendMessageForm
组件。注意,我们还绑定了this
方法handleSubmit
:
class SendMessageForm extends React.Component {
constructor() {
super()
this.state = {
message: ''
}
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleChange(e) {
this.setState({
message: e.target.value
})
}
handleSubmit(e) {
e.preventDefault()
this.props.sendMessage(this.state.message)
this.setState({
message: ''
})
}
render() {
return (
<form
onSubmit={this.handleSubmit}
className="send-message-form">
<input
onChange={this.handleChange}
value={this.state.message}
placeholder="Type your message and hit ENTER"
type="text" />
</form>
)
}
}
步骤 9:将消息发送到 Chatkit
现在我们可以将消息发送到 Chatkit 了。这项工作在组件中完成App
,我们将在其中创建一个名为 的方法this.sendMessage
:
sendMessage(text) {
this.currentUser.sendMessage({
text,
roomId: roomId
})
}
它需要一个参数(文本)并且它只是调用this.currentUser.sendMessage()
。
最后一步是将其<SendMessageForm>
作为 prop 传递给组件:
// App component
render() {
return (
<div className="app">
<Title />
<MessageList messages={this.state.messages} />
<SendMessageForm sendMessage={this.sendMessage} />
)
}
这样,我们就传递了处理程序,以便SendMessageForm
在提交表单时可以调用它。
步骤 10:创建标题组件
最后,我们来创建 Title 组件。它只是一个简单的函数组件,也就是说,它是一个返回 JSX 表达式的函数。
function Title() {
return <p class="title">My awesome chat app</p>
}
使用功能组件是一种很好的做法,因为它们比类组件具有更多的约束,这使得它们不易出现错误。
结果
有了这些,您就有了自己的聊天应用程序,可以用来与朋友聊天!
如果您一直坚持编码到最后,请给自己一点鼓励。
如果您想了解如何在此示例的基础上进一步构建,请查看我的免费课程,了解如何使用 React 创建聊天应用程序。
我们还提供免费的React 入门课程和长达 12 小时以上的React 训练营,让您从业余爱好者一路成长为专业的 React 开发人员。
感谢阅读!我叫 Per,是Scrimba的联合创始人,我热爱帮助人们学习新技能。如果您想及时收到新文章和资源的通知,请在Twitter上关注我。
鏂囩珷鏉ユ簮锛�https://dev.to/scrimba/how-to-build-a-react-js-chat-app-in-10-minutes-2fj3