ReactJS
Real Time
Implementasi Parse Live Query di Aplikasi Chat React
11 mnt
aplikasi obrolan react waktu nyata pendahuluan dalam panduan terakhir, anda lebih mengenal @parse/react @parse/react perpustakaan pembantu yang dengan cepat memungkinkan dukungan parse live query di aplikasi react anda perpustakaan ini ditulis sepenuhnya dalam typescript, di atas parse javascript sdk , dan saat ini berada di versi alpha sekarang, dalam panduan ini, anda akan menggunakan hook parse react dalam situasi realistis untuk membuat aplikasi obrolan langsung yang sederhana aplikasi ini terdiri dari dua komponen react yang menyoroti kegunaan live query dari parse dan juga menunjukkan semua yang perlu anda ketahui untuk membuat aplikasi langsung anda yang lengkap parse react native saat ini berada di versi alpha perpustakaan ini sedang dalam pengujian, jadi kami sarankan untuk melanjutkan dengan hati hati umpan balik anda sangat dihargai, jadi jangan ragu untuk menggunakan perpustakaan ini dan kirimkan pertanyaan serta kesan pertama anda dengan mengirim email ke community\@back4app com prasyarat untuk menyelesaikan tutorial ini, anda akan membutuhkan aplikasi react yang dibuat dan terhubung ke back4app selesaikan panduan sebelumnya agar anda dapat memiliki pemahaman yang lebih baik tentang hook parse react dan live query jika anda ingin menguji/menggunakan tata letak layar yang disediakan oleh panduan ini, anda harus mengatur ant design ant design perpustakaan tujuan untuk membangun aplikasi obrolan langsung di react menggunakan @parse/react @parse/react hook sebagai pengaktif untuk live query di parse 1 memahami dan membuat kelas basis data aplikasi obrolan akan terdiri dari dua kelas basis data kecil nama panggilan nama panggilan dan pesan pesan nama panggilan nama panggilan hanya memiliki satu field teks yang disebut nama nama dan akan mewakili pengguna dalam aplikasi pesan pesan akan menyimpan pesan teks yang dikirim antara dua pengguna, jadi perlu memiliki field teks yang disebut teks teks dan dua field pointer objek yang disebut pengirim pengirim dan penerima penerima , keduanya terkait dengan kelas nama panggilan nama panggilan jalankan potongan kode berikut di konsol javascript dasbor back4app anda untuk membuat kelas kelas ini dan mengisinya dengan beberapa contoh 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 mengaktifkan live query sekarang setelah anda membuat nama panggilan nama panggilan dan pesan pesan kelas, kita perlu mengaktifkannya dengan kemampuan live query pergi ke dasbor back4app anda dan navigasikan ke pengaturan aplikasi pengaturan aplikasi > pengaturan server pengaturan server > url server dan live query url server dan live query setelah mengaktifkan subdomain back4app anda, anda kemudian dapat mengaktifkan live query dan memilih kelas db mana yang akan diaktifkan pastikan untuk memilih kelas baru dan menyimpan perubahan hal selanjutnya adalah membuat aplikasi chat kita, yang terdiri dari dua komponen, chatsetup chatsetup dan livechat livechat 3 membuat komponen chat setup komponen ini bertanggung jawab untuk membuat dan mengatur objek pengirim dan penerima nickname nickname sambil juga berfungsi sebagai wadah untuk struktur komponen livechat livechat bagian setup hanya memiliki dua kolom input untuk nickname dan sebuah tombol yang memicu fungsi setup buat file baru di src src direktori anda yang disebut chatsetup js chatsetup js (atau chatsetup tsx chatsetup tsx ) dan gunakan kode berikut 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 }; perhatikan bahwa komponen livechat livechat hanya diinisialisasi dan dirender ketika proses pengaturan berhasil dan semua variabel status diatur dengan benar demikian pula, input pengaturan disembunyikan setelah proses dan tata letak komponen anak dirender 4 membuat komponen live chat komponen livechat livechat menangani pameran dan pengiriman pesan pesan antara dua nama panggilan nama panggilan yang diteruskan sebagai parameter saat inisialisasi di komponen inilah anda akhirnya akan menggunakan useparsequery useparsequery hook dari @parse/react @parse/react untuk mengatur live query yang akan mengambil objek pesan pesan yang terkait dengan instance chat ini buat file baru di src src direktori anda yang disebut livechat js livechat js (atau livechat tsx livechat tsx ) dan masukkan kode berikut 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 }; mari kita uraikan struktur komponen ini menjadi empat bagian, sehingga anda dapat lebih memahami tata letaknya di bagian atas kita memiliki parse query parse query dan pengaturan hook parse react di sini anda dapat melihat bagaimana props props parameter digunakan untuk memungkinkan kueri mengambil pesan yang kita inginkan; setelah itu, anda memiliki sendmessage sendmessage fungsi, yang akan membuat objek message message baru yang mengaitkannya dengan nickname nickname yang digunakan dalam instance chat ini ada juga fungsi pembantu untuk memformat nilai tanggal pesan; sekarang, di dalam kode jsx, kita memiliki status flag yang terkait dengan variabel hook parse react dan juga tombol muat ulang koneksi; terakhir, anda dapat melihat message message daftar di mana gaya item daftar yang dirender ditentukan oleh nilai pengirimnya di bagian bawah, kita memiliki bagian pengiriman pesan, dengan input teks sederhana dan sebuah tombol akhirnya, tambahkan kelas ini ke app css app css file anda jika anda ingin merender tata letak komponen sepenuhnya, dan mari kita lanjutkan untuk menguji aplikasi kita 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 menguji aplikasi obrolan silakan uji aplikasi obrolan langsung dengan mendeklarasikan dan memanggil chatsetup chatsetup komponen di app js app js anda (atau app tsx app tsx ) kode jsx anda berikut adalah contoh cara melakukannya 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; mulai aplikasi anda dengan menjalankan yarn start yarn start di konsol anda anda sekarang harus melihat layar berikut, di mana anda perlu memberi tahu nama panggilan pengirim dan penerima untuk mulai mengobrol untuk melihat lebih baik bagaimana aplikasi dan kueri langsung bekerja, buka aplikasi yang sama di dua jendela browser yang berbeda dan atur berdampingan segera setelah mengirim pesan di satu jendela, anda harus melihatnya muncul di jendela lain jika nama panggilan cocok dan koneksinya langsung kesimpulan di akhir panduan ini, anda telah belajar bagaimana menggunakan hook parse react untuk kueri langsung di parse dalam contoh aplikasi yang realistis