Issue
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 .
import Gun from "gun/gun";
import { IGunChain, IGunInstance } from "gun/types";
class GunService {
public gun: IGunInstance<any> | undefined;
public messageListener:
| IGunChain<any, IGunInstance<any>, IGunInstance<any>, "messages">
| undefined;
constructor() {
this.gun = Gun("http://localhost:4000" + "/gun");
this.messageListener = this.gun.get("messages");
}
public sendMessage(message: any) {
this.messageListener?.set(message);
}
}
export const gunServices = new GunService();
then in my component : get message on each new update
useEffect(() => {
gunServices.messageListener?.map().on((message) => {
setMessages((prevMessage) => [...prevMessage, message]);
});
}, []);
send message function
const onSendMessage = () => {
const message = {
senderUsername: "John Doe",
senderId: "Doe---id",
receiverUsername: "John Doe",
receiverId: "zizou_id",
message: messageValue,
date: Date.now().toLocaleString(),
time: Date.now().toLocaleString(),
};
gunServices.sendMessage(message);
setMessageValue("");
};
Solution
My simple fix for that was add useRef()
import { useState, useRef, useEffect } from "react";
useEffect(() => {
if (loaded.current !== false) return; // Added
gunServices.messageListener?.map().once().on((message) => {
setMessages((prevMessage) => [...prevMessage, message]);
loaded.current = true; // Added
});
}, []);
Answered By - Sebastian Korotkiewicz