前回の続きを書いていく。
次にチャット機能を作成するためにクライアント側に簡単なUIを作成した。
<div className={styles.container}>
<h2>チャットアプリ</h2>
<div className={styles.chatInputButton}>
<input type="text" placeholder="ちゃっと・・・"/>
<button>チャット送信</button>
</div>
</div>
そして、チャット機能を作成するためにまずメッセージを送信するために入力されたメッセージを格納する変数を作成する。
今回使用したのはHooksのUseStateというものである。
const [message, setMessage] = useState("");
参考にしている動画ではここの記述部分しか見せていなかったが、これだけの記述ではuseStateというものは動作しない。
このようなエラーを起こしてしまう。
エラーの内容を見れば、そもそもuseState自体定義されていない。
残念ながらお手本にした動画には詳しく述べている部分はないので調べてみた。すると、直ぐに解決した。
このuseStateという機能はreactのパッケージの一部のようだ。
そのため、クライアント側の記述の最初のimportの部分に以下のような記述を加えた。
import React, {useState} from "react"
すると、きちんと動作するようになった。
次に、チャット送信のボタンにonClick関数を指定し、handleSendMessage()という関数を呼び出す。
<button onClick={() => handleSendMessage()}>チャット送信</button>
そして、コードの上部にhandleSendMessage()を定義していく。
const handleSendMessage = () => {
//サーバーへ送信
socket.emit("send_message", {message: message});
setMessage("");
};
socket.emitは前回のブログでも述べたが、クライアントとサーバーの送受信においてonが受信、emitが送信である。
第1引数のこの場合"send_message"はサーバー側の受信の記述と統一する必要があるが、今のところなんでもいい。
そして、先程定めた変数を使用している。
変数の指定の仕方の癖は気になるが今回は流した。
ソケット通信を用いてメッセージを送信している。
ちなみに、setMessage("");という記述は送信後、messageの変数の中身を空にしている。
そして、クライアントからサーバーへ送信したものを今度はサーバー側で受け取る必要がある。
サーバー側のindex.jsに書き加える。
//クライアントと通信
io.on("connection", (socket) => {
console.log("クライアントと接続しました。");
//クライアントからの受信
socket.on("send_message", (data) => {
console.log(data);
//クライアントへ送信
io.emit("received_message", data);
});
先程も述べたが、クライアント側の送信時に定めた第1引数と同じものを第1引数とする。
この場合、通信が繋がっている場合のみ受信が行われるので通信の処理の一部に受信の記述をする。
そして、受信が行われたときだけクライアント側へ受け取ったデータを送信するので受信の際の処理の一部にクライアントへの送信を記述する。
今度は、サーバーからクライアントへデータの送信が行われたのでクライアント側でデータの受信を行う。
//サーバーから受信
socket.on("received_message", (data) => {
console.log(data);
setList([...list, data]);
});
サーバー側の送信の第1引数と統一する。そして、そのデータをチャットなので一覧として記述していく必要があるが今回はまたuseStateを用いてリストへ格納していき後にmap関数を用いて展開してく。
今回リストへ加える際、スプレッド構文というものを用いた。
軽く調べ見ると、
リスト内のすべての要素を参照しているのが...(スプレッド)というイメージた。
そして、[...list, data]はlistで定められているリストにdataを加えて新たなリストを作成しているという感じである。
最後に、画面上にリストに入力されたチャットの内容を表示する。
map関数を用いて
{list.map((chat) => (
<div className={styles.chatArea} key={chat.message}>
{chat.message}
</div>
))};
これはkeyが重複する可能性があるので好ましくないらしいがこれできちんと表示されるようになった。
以上。ご覧いただきありがとうございます。