I’m implementing gun.js in react application.But messages are duplicated on each render, and on each update. Can someone help to figure out what’s wrong with my code.
this my code .
JavaScript
x
20
20
1
import Gun from "gun/gun";
2
import { IGunChain, IGunInstance } from "gun/types";
3
4
class GunService {
5
public gun: IGunInstance<any> | undefined;
6
public messageListener:
7
| IGunChain<any, IGunInstance<any>, IGunInstance<any>, "messages">
8
| undefined;
9
10
constructor() {
11
this.gun = Gun("http://localhost:4000" + "/gun");
12
this.messageListener = this.gun.get("messages");
13
}
14
15
public sendMessage(message: any) {
16
this.messageListener?.set(message);
17
}
18
}
19
export const gunServices = new GunService();
20
then in my component : get message on each new update
JavaScript
1
6
1
useEffect(() => {
2
gunServices.messageListener?.map().on((message) => {
3
setMessages((prevMessage) => [prevMessage, message]);
4
});
5
}, []);
6
send message function
JavaScript
1
16
16
1
const onSendMessage = () => {
2
3
const message = {
4
senderUsername: "John Doe",
5
senderId: "Doe---id",
6
receiverUsername: "John Doe",
7
receiverId: "zizou_id",
8
message: messageValue,
9
date: Date.now().toLocaleString(),
10
time: Date.now().toLocaleString(),
11
};
12
13
gunServices.sendMessage(message);
14
setMessageValue("");
15
};
16
Advertisement
Answer
My simple fix for that was add useRef()
JavaScript
1
12
12
1
import { useState, useRef, useEffect } from "react";
2
3
useEffect(() => {
4
if (loaded.current !== false) return; // Added
5
6
gunServices.messageListener?.map().once().on((message) => {
7
setMessages((prevMessage) => [prevMessage, message]);
8
9
loaded.current = true; // Added
10
});
11
}, []);
12