-
Notifications
You must be signed in to change notification settings - Fork 0
[WRFE-70](feat): 래플, 이벤트 생성과정에 필요한 API 연동 #84
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
export const useTagQuery = ({itemsPerPage, uuid, prefix}: TagQueryParams) => | ||
useQuery({ | ||
queryKey: ['tags', itemsPerPage, uuid, prefix], | ||
queryFn: () => fetchTags({itemsPerPage, uuid, prefix}), | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tag 목록 조회 API가 Pagination API인 것 같은데 useQuery를 사용하신 이유가 있나요??
useInfiniteQuery
또는 useSuspenseInifniteQuery
를 사용해서 구현할 수 있을 것 같아서요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4cfd2d8
페이지 네이션 적용 수정 커밋입니다
const [inputValue, setInputValue] = useState(''); // 입력하는 값 | ||
const debouncedInputValue = useDebounce(inputValue); | ||
|
||
const [autocompleteTags, setAutocompleteTags] = useState<TagList[]>([]); // 서버에서 받아오는 태그 리스트 | ||
|
||
const [isNew, setIsNew] = useState<boolean>(true); // 새로 생성할지 말지 | ||
|
||
const [selectedTagNames, setSelectedTagNames] = useState<string[]>([]); // 화면에 보여지는 태그 리스트 | ||
|
||
const {mutateAsync: createTag} = useCreateTag(); | ||
const {isPending: isQueryPending, data} = useTagQuery({ | ||
itemsPerPage: 100, // | ||
uuid: '', | ||
prefix: debouncedInputValue.toLocaleLowerCase(), | ||
}); | ||
const serverTags = data?.items; | ||
|
||
useEffect(() => { | ||
if (!serverTags) return; | ||
|
||
setIsNew(true); | ||
|
||
const isExistingTag = serverTags.some(tag => tag.name === inputValue); | ||
|
||
if (isExistingTag) { | ||
const suggestions = serverTags.filter(tag => tag.name !== inputValue); | ||
setAutocompleteTags(suggestions); | ||
setIsNew(false); | ||
} else { | ||
setAutocompleteTags(serverTags); | ||
} | ||
}, [data, inputValue, serverTags]); | ||
|
||
const handleAddTag = async (tag: string, id: number) => { | ||
if (selectedTagNames.length >= 5 || selectedTagNames.includes(tag)) { | ||
setInputValue(''); | ||
return; | ||
} | ||
|
||
if (isNew && id === 0) { | ||
createTagAndAddToList({tag, createTag, tagIds, onTagChange}); | ||
} else if (!isNew && id === 0) { | ||
addTagFromUserInputIfDuplicate({tag, serverTags, tagIds, onTagChange}); | ||
} else { | ||
addTagFromServerData({id, tagIds, onTagChange}); | ||
} | ||
|
||
setSelectedTagNames(prev => [...prev, tag]); | ||
setInputValue(''); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
비지니스 로직을 hook으로 추상화 시키는건 어떨까요?!
특히 features 레이어에서 util에서 만든 유틸 함수들이 굳이 분리될 필요 없이 hook 내부에서 정의하고 사용해도 괜찮을 것 같다는 생각이 듭니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0a397fa
수정 커밋입니다!
export const createTagAndAddToList = async ({ | ||
tag, | ||
createTag, | ||
tagIds, | ||
onTagChange, | ||
}: CreateTagAndAddToList) => { | ||
try { | ||
const response = await createTag(tag); | ||
onTagChange([...tagIds, response.id]); | ||
} catch (error) { | ||
console.error('error:', error); | ||
} | ||
}; | ||
|
||
/** | ||
* id를 서버에서 받아온 태그 추가하는 곳 | ||
* but 서버에서 받아온 리스트중 사용자 입력값과 중복된 값은 리스트에서 제거하고 맨 위로 올리기 때문에 | ||
* id를 찾아서 제출태그 리스트에 넣어줌 | ||
*/ | ||
export const addTagFromUserInputIfDuplicate = ({ | ||
tag, | ||
serverTags, | ||
tagIds, | ||
onTagChange, | ||
}: AddTagFromUserInputIfDuplicate) => { | ||
const foundid = serverTags?.find(item => item.name === tag)?.id ?? 0; | ||
onTagChange([...tagIds, foundid]); | ||
}; | ||
|
||
/** | ||
* id를 서버에서 받아온 태그 추가하는 곳 | ||
*/ | ||
export const addTagFromServerData = ({ | ||
id, | ||
tagIds, | ||
onTagChange, | ||
}: AddTagFromServerData) => { | ||
onTagChange([...tagIds, id]); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
유틸 함수들을 features 레이어에서 분리하기 보다 사용하는 widgets 레이어에서 커스텀훅으로 포함시키는게 어떨까요??
widgets 레이어 안에 UI 안에서 비지니스 로직으로 드러내기 보다 내부적으로 hook으로 추상화시킨다면 해당 파일에 정의할 필요는 없을 것 같아요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
위 리뷰 커밋과 동일합니다!
const categoryItems = [ | ||
{ | ||
value: '1', | ||
name: '생활', | ||
}, | ||
{ | ||
value: '2', | ||
name: '가전-디지탈', | ||
}, | ||
{ | ||
value: '3', | ||
name: '행사', | ||
}, | ||
{ | ||
value: '4', | ||
name: '당일마감', | ||
}, | ||
]; | ||
const {data: categoryItems} = useCategoryQuery(); | ||
|
||
const tags = ['tag1', 'tag2']; | ||
if (!categoryItems) { | ||
return <div>loading...</div>; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
꼭 필요하진 않지만 Suspense를 사용해서 로딩을 선언적으로 처리하는 것도 깔끔할 것 같아요!
그러기 위해서는 useCategoryQuery 내부에서 useQuery 대신 useSuspenseQuery를 사용할 수 있습니다 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
funnel 사용 시 ReferenceError: window is not defined로 인해 500 에러가 발생하는걸 해결하기 위해 ssr: false 옵션을 적용하여 해결하였는데 이 과정에서, 클라이언트 컴포넌트에서 서버 액션을 호출해야 하는 구조가 생기면서 고려사항이 생겼는데, 이 부분을 우선은 논이슈로 두고, 현재는 useQuery를 사용하는 방식으로 유지하다가 추후에 useSuspenseQuery로 리팩토링해보면 좋을 것 같은데 어떻게 생각하시나요?
008916f
to
aef4aab
Compare
1355142
to
f81f535
Compare
📖 개요
💻 작업사항
래플 / 이벤트 API
태그 API
카테고리 API
이미지 API
💡 작성한 이슈 외에 작업한 사항
API 연동 외에 추가한 사항
-> 변경 전 : 시간은 자동으로 24:00으로 들어감
변경 후 : 시간을 설정함으로 원하는 시간에 당첨 및 마감 가능
✔️ check list