Function running multiple times

I’ve been stuck at this for a while now, and I just don’t know what to do.

This function makes it so all the TextButtons in the ScrollingFrame can be interacted with.

function RefreshInventorySelection()
	Main.Frame.InventoryContainer.ScrollingFrame.Visible = false
	Main.Frame.InventoryContainer.Loading.Visible = true
	for i,v in pairs(Main.Frame.InventoryContainer.ScrollingFrame:GetDescendants()) do
		if v:IsA("TextButton") then
			print(i, v)
			v.MouseEnter:Connect(function()
				Main.Hover:Play()
			end)
			v.MouseButton1Down:Connect(function()
				Main.Select:Play()
				RS.RemoteEvents.ItemEquip:FireServer(v.Text)
				v.Parent:Destroy()
				print(v.Name, v.Parent.Name, v.Parent.Parent.Name)
				RefreshInventorySelection()
			end)
		end
	end
	wait(1)
	Main.Frame.InventoryContainer.ScrollingFrame.Visible = true
	Main.Frame.InventoryContainer.Loading.Visible = false
end

The prints are how I found out it was running multiple times:

Now, only two other functions call RefreshInventorySelection:

for _,v in pairs(Main.Frame.EquipContainer:GetChildren()) do
	if v:IsA("ImageButton") then
		v.MouseEnter:Connect(function()
			Main.Hover:Play()
		end)
		v.Activated:Connect(function()
			Main.Select:Play()

			if v.ItemName.Text ~= "N/A" then
				for slot, item in pairs(Equips) do
					if v.Name ~= "OutfitEquip" then
						if v.Name == slot.."Equip" then
							RS.RemoteEvents.ItemUnequip:FireServer(item)
							item = "N/A"
							v.ItemName.Text = "N/A"
						end
					else
						RS.RemoteEvents.ItemUnequip:FireServer(item)
						item = "Traveler's Garments"
						v.ItemName.Text = "Traveler's Garments"
					end
				end
			end
			RefreshInventorySelection()
		end)
	end
end

RS.RemoteEvents.ItemUnequip.OnClientEvent:Connect(function(item, rarity)
	local IT = Main.Frame.InventoryContainer.ScrollingFrame.ItemTemplate:Clone()
	IT.Name = item
	IT.TextButton.Text = item
	IT.Parent = Main.Frame.InventoryContainer.ScrollingFrame
	IT.Visible = true
	RefreshInventorySelection()
end)

I’m not sure what I’m doing wrong.

function RefreshInventorySelection()
    Main.Frame.InventoryContainer.ScrollingFrame.Visible = false
    Main.Frame.InventoryContainer.Loading.Visible = true
    
    for i,v in pairs(Main.Frame.InventoryContainer.ScrollingFrame:GetDescendants()) do
        if v:IsA("TextButton") then
            print(i, v)
            v.MouseEnter:Connect(function()
                Main.Hover:Play()
            end)
            v.MouseButton1Down:Connect(function()
                Main.Select:Play()
                RS.RemoteEvents.ItemEquip:FireServer(v.Text)
                v.Parent:Destroy()
                print(v.Name, v.Parent.Name, v.Parent.Parent.Name)
            end)
        end
    end
    
    wait(1)
    Main.Frame.InventoryContainer.ScrollingFrame.Visible = true
    Main.Frame.InventoryContainer.Loading.Visible = false
end
-- Call RefreshInventorySelection() after modifying the inventory or when updating the UI
-- Example:
RS.RemoteEvents.ItemUnequip.OnClientEvent:Connect(function(item, rarity)
    local IT = Main.Frame.InventoryContainer.ScrollingFrame.ItemTemplate:Clone()
    IT.Name = item
    IT.TextButton.Text = item
    IT.Parent = Main.Frame.InventoryContainer.ScrollingFrame
    IT.Visible = true
    RefreshInventorySelection()
end)

This does not fix it, unfortunately.

when is the client event fired for the remote event handling the unequip?

You’re not disconnecting the v.MouseButtonDown connection. RefreshInventorySelection keeps firing, it’ll stack and it fires multiple times.

Suggestion: Only call refresh once, and don’t call refresh when you do mouseButton1Down