ReactJS
Real Time
使用Parse React Hook构建实时聊天应用程序示例
10 分
react 聊天应用 实时 介绍 在上一个指南中,您了解了更多关于 @parse/react @parse/react 助手库,该库可以快速在您的 react 应用程序中启用 parse 实时查询支持。该库完全用 typescript 编写,基于 parse javascript sdk , 目前处于 alpha 版本。 现在,在本指南中,您将使用 parse react 钩子在创建一个简单的实时聊天应用程序的实际情况下。该应用程序由两个 react 组件组成,突出了 parse 的实时查询的实用性,并展示了您创建完整实时应用所需了解的一切。 parse react native 目前处于 alpha 版本。该库正在测试中,因此我们建议谨慎使用。我们非常感谢您的反馈,因此请随时使用该库,并通过发送电子邮件至 community\@back4app com 向我们提出您的问题和初步印象。 先决条件 要完成本教程,您需要: 一个已创建并 连接到 back4app 完成之前的指南,以便更好地理解 parse react 钩子和实时查询 如果您想测试/使用本指南提供的屏幕布局,您应该设置 ant design ant design 库 目标 使用 @parse/react @parse/react 钩子作为 parse 上实时查询的启用器,构建一个实时聊天应用程序。 1 理解和创建数据库类 聊天应用程序将由两个小数据库类组成: 昵称 昵称 和 消息 消息 昵称 昵称 只有一个名为 名称 名称 的文本字段,并将代表应用程序中的用户。 消息 消息 将保存两个用户之间发送的任何文本消息,因此它需要有一个名为 文本 文本 的文本字段和两个对象指针字段,分别称为 发送者 发送者 和 接收者 接收者 , 两者都与 昵称 昵称 类相关。 在您的 back4app 仪表板的 javascript 控制台上运行以下代码片段,以创建这些类并用一些示例填充它们。 1 // create nicknames 2 let nicknamea = new parse object('nickname'); 3 nicknamea set('name', 'smartboy22'); 4 nicknamea = await nicknamea save(); 5 let nicknameb = new parse object('nickname'); 6 nicknameb set('name', 'clevergirl23'); 7 nicknameb = await nicknameb save(); 8	 9 // create message linked to nicknames 10 let message = new parse object('message'); 11 message set('text', 'hi! how are you?'); 12 message set('sender', nicknamea); 13 message set('receiver', nicknamea); 14 message = await message save(); 15 console log('success'); 2 启用实时查询 现在您已经创建了 昵称 昵称 和 消息 消息 类,我们需要为它们启用实时查询功能。请转到您的 back4app 仪表板并导航到 应用设置 应用设置 > 服务器设置 服务器设置 > 服务器 url 和实时查询 服务器 url 和实时查询 在激活您的 back4app 子域后,您可以激活实时查询并选择哪些数据库类将启用它。确保选择新类并保存更改。 接下来要做的是创建我们的聊天应用程序,它由两个组件组成, chatsetup chatsetup 和 livechat livechat 3 创建聊天设置组件 这个组件负责创建和设置发送者和接收者 昵称 昵称 对象,同时也作为 livechat livechat 组件结构的容器。设置部分的布局只有两个用于昵称的输入字段和一个触发设置功能的按钮。在你的 src src 目录中创建一个名为 chatsetup js chatsetup js (或 chatsetup tsx chatsetup tsx ) 并使用以下代码 chatsetup js 1 import react, { usestate } from "react"; 2 import " /app css"; 3 import { button, input } from "antd"; 4 import parse from "parse"; 5 import { livechat } from " /livechat"; 6	 7 export const chatsetup = () => { 8 // state variables holding input values and results 9 const \[sendernicknameinput, setsendernicknameinput] = usestate(""); 10 const \[sendernicknameid, setsendernicknameid] = usestate(null); 11 const \[receivernicknameinput, setreceivernicknameinput] = usestate(""); 12 const \[receivernicknameid, setreceivernicknameid] = usestate(null); 13	 14 // create or retrieve nickname objects and start livechat component 15 const startlivechat = async () => { 16 const sendernicknamename = sendernicknameinput; 17 const receivernicknamename = receivernicknameinput; 18	 19 // check if user informed both nicknames 20 if (sendernicknamename === null || receivernicknamename === null) { 21 alert("please inform both sender and receiver nicknames!"); 22 return false; 23 } 24	 25 // check if sender nickname already exists, if not create new parse object 26 let sendernicknameobject = null; 27 try { 28 const senderparsequery = new parse query("nickname"); 29 senderparsequery equalto("name", sendernicknamename); 30 const senderparsequeryresult = await senderparsequery first(); 31 if ( 32 senderparsequeryresult !== undefined && 33 senderparsequeryresult !== null 34 ) { 35 sendernicknameobject = senderparsequeryresult; 36 } else { 37 sendernicknameobject = new parse object("nickname"); 38 sendernicknameobject set("name", sendernicknamename); 39 sendernicknameobject = await sendernicknameobject save(); 40 } 41 } catch (error) { 42 alert(error); 43 return false; 44 } 45	 46 // check if receiver nickname already exists, if not create new parse object 47 let receivernicknameobject = null; 48 try { 49 const receiverparsequery = new parse query("nickname"); 50 receiverparsequery equalto("name", receivernicknamename); 51 const receiverparsequeryresult = await receiverparsequery first(); 52 if ( 53 receiverparsequeryresult !== undefined && 54 receiverparsequeryresult !== null 55 ) { 56 receivernicknameobject = receiverparsequeryresult; 57 } else { 58 receivernicknameobject = new parse object("nickname"); 59 receivernicknameobject set("name", receivernicknamename); 60 receivernicknameobject = await receivernicknameobject save(); 61 } 62 } catch (error) { 63 alert(error); 64 return false; 65 } 66	 67 // set nickname objects ids, so live chat component is instantiated 68 setsendernicknameid(sendernicknameobject id); 69 setreceivernicknameid(receivernicknameobject id); 70 return true; 71 }; 72	 73 return ( 74 \<div> 75 \<div classname="header"> 76 \<img 77 classname="header logo" 78 alt="back4app logo" 79 src={ 80 "https //blog back4app com/wp content/uploads/2019/05/back4app white logo 500px png" 81 } 82 /> 83 \<p classname="header text bold">{"react on back4app"}\</p> 84 \<p classname="header text">{"live query chat app"}\</p> 85 \</div> 86 \<div classname="container"> 87 {sendernicknameid === null && receivernicknameid === null && ( 88 \<div> 89 \<input 90 classname="form input" 91 value={sendernicknameinput} 92 onchange={(event) => setsendernicknameinput(event target value)} 93 placeholder={"sender (your) nickname"} 94 size="large" 95 /> 96 \<input 97 classname="form input" 98 value={receivernicknameinput} 99 onchange={(event) => setreceivernicknameinput(event target value)} 100 placeholder={"receiver (their) nickname"} 101 size="large" 102 /> 103 \<button 104 type="primary" 105 classname="form button" 106 color={"#208aec"} 107 size={"large"} 108 onclick={startlivechat} 109 > 110 start live chat 111 \</button> 112 \</div> 113 )} 114 {sendernicknameid !== null && receivernicknameid !== null && ( 115 \<livechat 116 sendernicknamename={sendernicknameinput} 117 sendernicknameid={sendernicknameid} 118 receivernicknamename={receivernicknameinput} 119 receivernicknameid={receivernicknameid} 120 /> 121 )} 122 \</div> 123 \</div> 124 ); 125 }; chatsetup tsx 1 import react, { usestate, fc, reactelement } from "react"; 2 import " /app css"; 3 import { button, input } from "antd"; 4 import { livechat } from " /livechat"; 5 import parse from "parse"; 6	 7 export const chatsetup fc<{}> = () reactelement => { 8 // state variables holding input values and results 9 const \[sendernicknameinput, setsendernicknameinput] = usestate(""); 10 const \[sendernicknameid, setsendernicknameid] = usestate\<string | null>(null); 11 const \[receivernicknameinput, setreceivernicknameinput] = usestate(""); 12 const \[receivernicknameid, setreceivernicknameid] = usestate\<string | null>(null); 13	 14 // create or retrieve nickname objects and start livechat component 15 const startlivechat = async () promise\<boolean> => { 16 const sendernicknamename string = sendernicknameinput; 17 const receivernicknamename string = receivernicknameinput; 18	 19 // check if user informed both nicknames 20 if (sendernicknamename === "" || receivernicknamename === "") { 21 alert("please inform both sender and receiver nicknames!"); 22 return false; 23 } 24	 25 // check if sender nickname already exists, if not create new parse object 26 let sendernicknameobject parse object | null = null; 27 try { 28 const senderparsequery parse query = new parse query("nickname"); 29 senderparsequery equalto("name", sendernicknamename); 30 const senderparsequeryresult parse object | undefined = await senderparsequery first(); 31 if ( 32 senderparsequeryresult !== undefined 33 ) { 34 sendernicknameobject = senderparsequeryresult; 35 } else { 36 sendernicknameobject = new parse object("nickname"); 37 if (sendernicknameobject !== null) { 38 sendernicknameobject set("name", sendernicknamename); 39 sendernicknameobject = await sendernicknameobject save(); 40 } 41 } 42 } catch (error) { 43 alert(error); 44 return false; 45 } 46	 47 // check if receiver nickname already exists, if not create new parse object 48 let receivernicknameobject parse object | null = null; 49 try { 50 const receiverparsequery parse query = new parse query("nickname"); 51 receiverparsequery equalto("name", receivernicknamename); 52 const receiverparsequeryresult parse object | undefined = await receiverparsequery first(); 53 if ( 54 receiverparsequeryresult !== undefined 55 ) { 56 receivernicknameobject = receiverparsequeryresult; 57 } else { 58 receivernicknameobject = new parse object("nickname"); 59 if (receivernicknameobject !== null) { 60 receivernicknameobject set("name", receivernicknamename); 61 receivernicknameobject = await receivernicknameobject save(); 62 } 63 } 64 } catch (error any) { 65 alert(error); 66 return false; 67 } 68	 69 // set nickname objects ids, so live chat component is instantiated 70 if (sendernicknameobject !== null && receivernicknameobject !== null) { 71 setsendernicknameid(sendernicknameobject id); 72 setreceivernicknameid(receivernicknameobject id); 73 } 74 return true; 75 }; 76	 77 return ( 78 \<div> 79 \<div classname="header"> 80 \<img 81 classname="header logo" 82 alt="back4app logo" 83 src={ 84 "https //blog back4app com/wp content/uploads/2019/05/back4app white logo 500px png" 85 } 86 /> 87 \<p classname="header text bold">{"react on back4app"}\</p> 88 \<p classname="header text">{"live query chat app"}\</p> 89 \</div> 90 \<div classname="container"> 91 {sendernicknameid === null && receivernicknameid === null && ( 92 \<div> 93 \<input 94 classname="form input" 95 value={sendernicknameinput} 96 onchange={(event) => setsendernicknameinput(event target value)} 97 placeholder={"sender (your) nickname"} 98 size="large" 99 /> 100 \<input 101 classname="form input" 102 value={receivernicknameinput} 103 onchange={(event) => setreceivernicknameinput(event target value)} 104 placeholder={"receiver (their) nickname"} 105 size="large" 106 /> 107 \<button 108 type="primary" 109 classname="form button" 110 color={"#208aec"} 111 size={"large"} 112 onclick={startlivechat} 113 > 114 start live chat 115 \</button> 116 \</div> 117 )} 118 {sendernicknameid !== null && receivernicknameid !== null && ( 119 \<livechat 120 sendernicknamename={sendernicknameinput} 121 sendernicknameid={sendernicknameid} 122 receivernicknamename={receivernicknameinput} 123 receivernicknameid={receivernicknameid} 124 /> 125 )} 126 \</div> 127 \</div> 128 ); 129 }; 请注意, livechat livechat 组件仅在设置过程成功且所有状态变量正确设置时初始化和渲染。同样,设置输入在过程结束后被隐藏,子组件布局被渲染。 4 创建实时聊天组件 该 livechat livechat 组件处理展示和发送 消息 消息 在两个 昵称 昵称 作为参数传递给它的初始化。正是在这个组件中,您将最终使用 useparsequery useparsequery 钩子来自 @parse/react @parse/react 来设置将检索与此聊天实例相关的任何 消息 消息 对象的实时查询。在您的 src src 目录中创建一个名为 livechat js livechat js (或 livechat tsx livechat tsx ) 的新文件,并插入以下代码。 livechat js 1 import react, { usestate } from "react"; 2 import " /app css"; 3 import { button, input, tooltip } from "antd"; 4 import { syncoutlined } from "@ant design/icons"; 5 import parse from "parse"; 6 import { useparsequery } from "@parse/react"; 7	 8 export const livechat = (props) => { 9 // state variable to hold message text input 10 const \[messageinput, setmessageinput] = usestate(""); 11	 12 // create parse query for live querying using useparsequery hook 13 const parsequery = new parse query("message"); 14 // get messages that involve both nicknames 15 parsequery containedin("sender", \[ 16 props sendernicknameid, 17 props receivernicknameid, 18 ]); 19 parsequery containedin("receiver", \[ 20 props sendernicknameid, 21 props receivernicknameid, 22 ]); 23 // set results ordering 24 parsequery ascending("createdat"); 25	 26 // include nickname fields, to enable name getting on list 27 parsequery includeall(); 28	 29 // declare hook and variables to hold hook responses 30 const { islive, isloading, issyncing, results, count, error, reload } = 31 useparsequery(parsequery, { 32 enablelocaldatastore true, // enables cache in local datastore (default true) 33 enablelivequery true, // enables live query for real time update (default true) 34 }); 35	 36 // message sender handler 37 const sendmessage = async () => { 38 try { 39 const messagetext = messageinput; 40	 41 // get sender and receiver nickname parse objects 42 const sendernicknameobjectquery = new parse query("nickname"); 43 sendernicknameobjectquery equalto("objectid", props sendernicknameid); 44 let sendernicknameobject = await sendernicknameobjectquery first(); 45 const receivernicknameobjectquery = new parse query("nickname"); 46 receivernicknameobjectquery equalto("objectid", props receivernicknameid); 47 let receivernicknameobject = await receivernicknameobjectquery first(); 48	 49 // create new message object and save it 50 let message = new parse object("message"); 51 message set("text", messagetext); 52 message set("sender", sendernicknameobject); 53 message set("receiver", receivernicknameobject); 54 message save(); 55	 56 // clear input 57 setmessageinput(""); 58 } catch (error) { 59 alert(error); 60 } 61 }; 62	 63 // helper to format createdat value on message 64 const formatdatetotime = (date) => { 65 return `${date gethours()} ${date getminutes()} ${date getseconds()}`; 66 }; 67	 68 return ( 69 \<div> 70 \<div classname="flex between"> 71 \<h2 class="list heading">{`${props sendernicknamename} sending, ${props receivernicknamename} receiving!`}\</h2> 72 \<tooltip title="reload"> 73 \<button 74 onclick={reload} 75 type="primary" 76 shape="circle" 77 icon={\<syncoutlined />} 78 /> 79 \</tooltip> 80 \</div> 81 {results && ( 82 \<div classname="messages"> 83 {results 84 sort((a, b) => a get("createdat") > b get("createdat")) 85 map((result) => ( 86 \<div 87 key={result id} 88 classname={ 89 result get("sender") id === props sendernicknameid 90 ? "message sent" 91 "message received" 92 } 93 > 94 \<p classname="message bubble">{result get("text")}\</p> 95 \<p classname="message time"> 96 {formatdatetotime(result get("createdat"))} 97 \</p> 98 \<p classname="message name"> 99 {result get("sender") get("name")} 100 \</p> 101 \</div> 102 ))} 103 \</div> 104 )} 105 \<div classname="new message"> 106 \<h2 classname="new message title">new message\</h2> 107 \<input 108 classname="form input" 109 value={messageinput} 110 onchange={(event) => setmessageinput(event target value)} 111 placeholder={"your message "} 112 size="large" 113 /> 114 \<button 115 type="primary" 116 classname="form button" 117 color={"#208aec"} 118 size={"large"} 119 onclick={sendmessage} 120 > 121 send message 122 \</button> 123 \</div> 124 \<div> 125 {isloading && \<p>{"loading…"}\</p>} 126 {issyncing && \<p>{"syncing…"}\</p>} 127 {islive ? \<p>{"status live"}\</p> \<p>{"status offline"}\</p>} 128 {error && \<p>{error message}\</p>} 129 {count && \<p>{`count ${count}`}\</p>} 130 \</div> 131 \</div> 132 ); 133 }; livechat tsx 1 import react, { usestate, fc, reactelement } from "react"; 2 import " /app css"; 3 import { button, input, tooltip } from "antd"; 4 import { syncoutlined } from "@ant design/icons"; 5 import parse from "parse"; 6 import { useparsequery } from "@parse/react"; 7	 8 type livechatprops = { 9 sendernicknameid string, 10 sendernicknamename string, 11 receivernicknameid string, 12 receivernicknamename string, 13 } 14	 15 export const livechat fc\<livechatprops> = (props livechatprops) reactelement => { 16 const parse = require("parse/dist/parse min js"); 17 // state variable to hold message text input 18 const \[messageinput, setmessageinput] = usestate(""); 19	 20 // create parse query for live querying using useparsequery hook 21 const parsequery parse query = new parse query("message"); 22 // get messages that involve both nicknames 23 parsequery containedin("sender", \[ 24 props sendernicknameid, 25 props receivernicknameid, 26 ]); 27 parsequery containedin("receiver", \[ 28 props sendernicknameid, 29 props receivernicknameid, 30 ]); 31 // set results ordering 32 parsequery ascending("createdat"); 33	 34 // include nickname fields, to enable name getting on list 35 parsequery includeall(); 36	 37 // declare hook and variables to hold hook responses 38 const { islive, isloading, issyncing, results, count, error, reload } = 39 useparsequery(parsequery, { 40 enablelocaldatastore true, // enables cache in local datastore (default true) 41 enablelivequery true, // enables live query for real time update (default true) 42 }); 43	 44 // message sender handler 45 const sendmessage = async () => { 46 try { 47 const messagetext string = messageinput; 48	 49 // get sender and receiver nickname parse objects 50 const sendernicknameobjectquery parse query = new parse query("nickname"); 51 sendernicknameobjectquery equalto("objectid", props sendernicknameid); 52 let sendernicknameobject parse object | undefined = await sendernicknameobjectquery first(); 53 const receivernicknameobjectquery parse query = new parse query("nickname"); 54 receivernicknameobjectquery equalto("objectid", props receivernicknameid); 55 let receivernicknameobject parse object | undefined = await receivernicknameobjectquery first(); 56	 57 // create new message object and save it 58 let message parse object = new parse object("message"); 59 message set("text", messagetext); 60 message set("sender", sendernicknameobject); 61 message set("receiver", receivernicknameobject); 62 message save(); 63	 64 // clear input 65 setmessageinput(""); 66 } catch (error any) { 67 alert(error); 68 } 69 }; 70	 71 // helper to format createdat value on message 72 const formatdatetotime = (date date) string => { 73 return `${date gethours()} ${date getminutes()} ${date getseconds()}`; 74 }; 75	 76 return ( 77 \<div> 78 \<div classname="flex between"> 79 \<h2 class="list heading">{`${props sendernicknamename} sending, ${props receivernicknamename} receiving!`}\</h2> 80 \<tooltip title="reload"> 81 \<button 82 onclick={reload} 83 type="primary" 84 shape="circle" 85 icon={\<syncoutlined />} 86 /> 87 \</tooltip> 88 \</div> 89 {results && ( 90 \<div classname="messages"> 91 {results 92 sort((a, b) => a get("createdat") > b get("createdat")) 93 map((result) => ( 94 \<div 95 key={result id} 96 classname={ 97 result get("sender") id === props sendernicknameid 98 ? "message sent" 99 "message received" 100 } 101 > 102 \<p classname="message bubble">{result get("text")}\</p> 103 \<p classname="message time"> 104 {formatdatetotime(result get("createdat"))} 105 \</p> 106 \<p classname="message name"> 107 {result get("sender") get("name")} 108 \</p> 109 \</div> 110 ))} 111 \</div> 112 )} 113 \<div classname="new message"> 114 \<h2 classname="new message title">new message\</h2> 115 \<input 116 classname="form input" 117 value={messageinput} 118 onchange={(event) => setmessageinput(event target value)} 119 placeholder={"your message "} 120 size="large" 121 /> 122 \<button 123 type="primary" 124 classname="form button" 125 color={"#208aec"} 126 size={"large"} 127 onclick={sendmessage} 128 > 129 send message 130 \</button> 131 \</div> 132 \<div> 133 {isloading && \<p>{"loading…"}\</p>} 134 {issyncing && \<p>{"syncing…"}\</p>} 135 {islive ? \<p>{"status live"}\</p> \<p>{"status offline"}\</p>} 136 {error && \<p>{error message}\</p>} 137 {count && \<p>{`count ${count}`}\</p>} 138 \</div> 139 \</div> 140 ); 141 }; 让我们将这个组件结构分解为四个部分,以便您更好地理解其布局: 在顶部,我们有消息的 parse query parse query 和 parse react hook 设置。在这里,您可以看到 props props 参数是如何被用来使查询能够检索我们想要的消息; 之后,您有 sendmessage sendmessage 函数,它将创建一个新的 message message 对象,将其与此聊天实例中使用的 nickname nickname 关联。还有一个帮助函数用于格式化消息日期值; 现在,在 jsx 代码中,我们有与 parse react hook 变量相关的状态标志,以及连接重载按钮; 最后,您可以看到 message message 列表,其中渲染的列表项样式由其发送者值决定。在底部,我们有消息发送部分,包含一个简单的文本输入和一个按钮。 最后,如果您想完全渲染组件布局,请将这些类添加到您的 app css app css 文件中,让我们继续测试我们的应用程序。 app css 1 @import ' antd/dist/antd css'; 2	 3 html { 4 box sizing border box; 5 outline none; 6 overflow auto; 7 } 8	 9 body { 10 margin 0; 11 background color #fff; 12 } 13	 14 , 15 before, 16 after { 17 margin 0; 18 padding 0; 19 box sizing inherit; 20 } 21	 22 h1, 23 h2, 24 h3, 25 h4, 26 h5, 27 h6 { 28 margin 0; 29 font weight bold; 30 } 31	 32 li { 33 list style none; 34 } 35	 36 p { 37 margin 0; 38 } 39	 40 flex between { 41 display flex; 42 align items center; 43 justify content space between; 44 } 45	 46 list heading { 47 font weight bold; 48 } 49	 50 app { 51 text align center; 52 } 53	 54 container { 55 width 100%; 56 max width 500px; 57 margin auto; 58 padding 20px 0; 59 text align left; 60 } 61	 62 header { 63 align items center; 64 padding 25px 0; 65 background color #208aec; 66 } 67	 68 header logo { 69 height 55px; 70 margin bottom 20px; 71 object fit contain; 72 } 73	 74 header text bold { 75 margin bottom 3px; 76 color rgba(255, 255, 255, 0 9); 77 font size 16px; 78 font weight bold; 79 } 80	 81 header text { 82 color rgba(255, 255, 255, 0 9); 83 font size 15px; 84 } 85	 86 heading { 87 font size 22px; 88 } 89	 90 form wrapper { 91 margin top 20px; 92 margin bottom 10px; 93 } 94	 95 form input { 96 margin bottom 20px; 97 } 98	 99 form button { 100 width 100%; 101 } 102	 103 messages { 104 margin top 25px; 105 } 106	 107 message sent { 108 position relative; 109 width 50%; 110 margin left auto; 111 } 112	 113 message received { 114 position relative; 115 width 50%; 116 } 117	 118 message bubble { 119 padding 12px; 120 border radius 25px; 121 background color rgba(0, 0, 0, 0 2); 122 } 123	 124 message sent message bubble { 125 background color #1e88e5; 126 color #fff; 127 } 128	 129 message time { 130 position absolute; 131 top 35%; 132 left 62px; 133 font size 13px; 134 color rgba(0, 0, 0, 0 35); 135 transform translatey( 50%); 136 } 137	 138 message sent message time { 139 left initial; 140 right 62px; 141 } 142	 143 message name { 144 margin top 5px; 145 color rgba(0, 0, 0, 0 55); 146 font size 13px; 147 font weight 600; 148 } 149	 150 message sent message name { 151 text align right; 152 } 153	 154 new message { 155 padding top 15px; 156 margin top 20px; 157 margin bottom 10px; 158 border top 1px solid rgba(0, 0, 0, 0 12); 159 } 160	 161 new message title { 162 margin bottom 15px; 163 } 5 测试聊天应用程序 继续测试实时聊天应用程序,通过在你的 chatsetup chatsetup 组件上声明和调用 app js app js (或 app tsx app tsx ) jsx 代码。以下是你可以如何做到的示例 app js or app tsx 1 import react from "react"; 2 import " /app css"; 3 import { initializeparse } from "@parse/react"; 4 import { chatsetup } from " /chatsetup"; 5	 6 // your parse initialization configuration goes here 7 // note the live query url instead of the regular server url 8 const parse application id = "your parse application id"; 9 // const parse server url = "https //parseapi back4app com/"; 10 const parse live query url = "https //your app name b4a io/"; 11 const parse javascript key = "your parse javascript key"; 12	 13 // initialize parse using @parse/react instead of regular parse js sdk 14 initializeparse( 15 parse live query url, 16 parse application id, 17 parse javascript key 18 ); 19	 20 function app() { 21 return ( 22 \<div classname="app"> 23 \<chatsetup /> 24 \</div> 25 ); 26 } 27	 28 export default app; 通过在控制台运行 yarn start yarn start 启动你的应用程序。现在你应该看到以下屏幕,在其中你需要输入发送和接收的昵称以开始聊天。 为了更好地查看应用程序和实时查询的工作情况,在两个不同的浏览器窗口中打开相同的应用程序并将它们并排放置。在一个窗口中发送消息后,如果昵称匹配且连接是实时的,你应该会看到它在另一个窗口中弹出。 结论 在本指南的最后,你学习了如何在一个现实的应用示例中使用 parse react 钩子进行实时查询。