From 28a4f63d10378e90a22f237de0c38f2200b547fc Mon Sep 17 00:00:00 2001 From: Pramod Mahajan Date: Sun, 18 May 2025 02:14:40 +0530 Subject: [PATCH] modfified TagInput for prevent multiple rendering --- src/components/common/TagInput.jsx | 85 ++++++++++++++---------------- 1 file changed, 41 insertions(+), 44 deletions(-) diff --git a/src/components/common/TagInput.jsx b/src/components/common/TagInput.jsx index cdc88afb..c40a278f 100644 --- a/src/components/common/TagInput.jsx +++ b/src/components/common/TagInput.jsx @@ -1,30 +1,28 @@ -import { useFormContext } from "react-hook-form"; +import { useFormContext, useWatch } from "react-hook-form"; import React, { useEffect, useState } from "react"; -import { useDispatch } from "react-redux"; -import { changeMaster } from "../../slices/localVariablesSlice"; const TagInput = ({ label = "Tags", name = "tags", - placeholder = "Start typing to add...", + placeholder = "Start typing to add... like employee, manager", color = "#e9ecef", options = [], }) => { const [tags, setTags] = useState([]); const [input, setInput] = useState(""); const [suggestions, setSuggestions] = useState([]); - const { setValue, trigger } = useFormContext(); - const dispatch = useDispatch(); + const { setValue, trigger, control } = useFormContext(); + const watchedTags = useWatch({ control, name }); - useEffect(() => { - setValue( - name, - tags.map((tag) => ({ - id: tag.id ?? null, - name: tag.name, - })) - ); - }, [ tags, name, setValue ] ); + +useEffect(() => { + if ( + Array.isArray(watchedTags) && + JSON.stringify(tags) !== JSON.stringify(watchedTags) + ) { + setTags(watchedTags); + } +}, [JSON.stringify(watchedTags)]); useEffect(() => { if (input.trim() === "") { @@ -32,29 +30,34 @@ const TagInput = ({ } else { const filtered = options?.filter( (opt) => - opt?.name?.toLowerCase()?.includes(input?.toLowerCase()) && - !tags?.some((tag) => tag?.name === opt?.name) + opt?.name?.toLowerCase()?.includes(input.toLowerCase()) && + !tags?.some((tag) => tag.name === opt.name) ); setSuggestions(filtered); } }, [input, options, tags]); - const addTag = async ( tagObj ) => - { - if (!tags.some((tag) => tag.id === tagObj.id)) { - const cleanedTag = { - id: tagObj.id ?? null, - name: tagObj.name, - }; - const newTags = [...tags, cleanedTag]; - setTags(newTags); - setValue(name, newTags, { shouldValidate: true }); // ✅ only id + name - await trigger(name); - setInput(""); - setSuggestions([]); - } -}; + const addTag = async (tagObj) => { + if (!tags.some((tag) => tag.name === tagObj.name)) { + const cleanedTag = { + id: tagObj.id ?? null, + name: tagObj.name, + }; + const newTags = [...tags, cleanedTag]; + setTags(newTags); + setValue(name, newTags, { shouldValidate: true }); + await trigger(name); + setInput(""); + setSuggestions([]); + } + }; + const removeTag = (indexToRemove) => { + const newTags = tags.filter((_, i) => i !== indexToRemove); + setTags(newTags); + setValue(name, newTags, { shouldValidate: true }); + trigger(name); + }; const handleInputKeyDown = (e) => { if (e.key === "Enter" && input.trim() !== "") { @@ -69,7 +72,7 @@ const TagInput = ({ name: input.trim(), description: input.trim(), }; - addTag(newTag); // Call async function (not awaiting because it's UI input) + addTag(newTag); } else if (e.key === "Backspace" && input === "") { setTags((prev) => prev.slice(0, -1)); } @@ -79,13 +82,6 @@ const TagInput = ({ addTag(suggestion); }; - const removeTag = (indexToRemove) => { - const newTags = tags.filter((_, i) => i !== indexToRemove); - setTags(newTags); - setValue(name, newTags, { shouldValidate: true }); - trigger(name); - }; - const backgroundColor = color || "#f8f9fa"; const iconColor = `var(--bs-${color})`; @@ -120,6 +116,7 @@ const TagInput = ({ /> ))} + dispatch(changeMaster("Contact Tag"))} /> {suggestions.length > 0 && (