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(""); };
Advertisement
Answer
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 }); }, []);