| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 |
- 'use client';
- // D3 장착 지위 아이템 배치 조회 훅 — 여러 작성자 ID 를 모아 한 번에 GET /api/members/equipped-items?ids=.
- // 댓글 목록/프로필에서 작성자별 배지·닉네임 이펙트 렌더용. 익명 허용.
- import { useEffect, useState } from 'react';
- import { fetchApi } from '@/lib/utils/client';
- import type { EquippedItem, EquippedItemsResponse } from '@/types/reward';
- type EquippedMap = Record<number, EquippedItem[]>;
- export default function useEquippedItems(memberIDs: (number|null|undefined)[]): EquippedMap
- {
- const [map, setMap] = useState<EquippedMap>({});
- // 유효 ID 만 정렬·중복 제거해 안정적인 key 생성 (불필요한 재조회 방지)
- const ids = Array.from(new Set(memberIDs.filter((id): id is number => typeof id === 'number' && id > 0))).sort((a, b) => a - b);
- const key = ids.join(',');
- useEffect(() => {
- if (ids.length === 0) {
- setMap({});
- return;
- }
- let cancelled = false;
- (async () => {
- const res = await fetchApi<EquippedItemsResponse>(`/api/members/equipped-items?ids=${key}`, { silent: true });
- if (cancelled) {
- return;
- }
- if (res.success && res.data) {
- const next: EquippedMap = {};
- for (const m of res.data.members) {
- next[m.memberID] = m.items;
- }
- setMap(next);
- }
- else {
- setMap({});
- }
- })();
- return () => {
- cancelled = true;
- };
- }, [key]); // eslint-disable-line react-hooks/exhaustive-deps
- return map;
- }
|