-
Notifications
You must be signed in to change notification settings - Fork 4
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
홈 화면 서스펜스 범위 재지정 및 셀렉트 컴포넌트 리팩터링 #840
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
2f988ea
feat: (#839) 셀렉트와 게시글 목록 본문을 분리하고 서스펜스 위치 이동
Gilpop8663 e7dd2e9
refactor: (#839) 셀렉트 내부의 상태를 커스텀훅으로 이동
Gilpop8663 e1a917d
style: (#839) 스켈레톤에 패딩 옵션 추가
Gilpop8663 867f2f0
refactor: (#839) 변수명, 함수명 수정
Gilpop8663 7fee8bd
feat: (#839) 회원 탈퇴 api 주소를 /members/me/delete에서 /auth/members/me/del…
Gilpop8663 a2c9658
feat: (#839) msw 회원 탈퇴 주소 변경
Gilpop8663 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,87 +1,86 @@ | ||
import React, { useContext, useEffect, useRef } from 'react'; | ||
import React, { MouseEvent, Suspense, useContext, useRef } from 'react'; | ||
|
||
import { useSelect } from '@hooks'; | ||
|
||
import { AuthContext } from '@hooks/context/auth'; | ||
import { PostOptionContext } from '@hooks/context/postOption'; | ||
import { usePostList } from '@hooks/query/usePostList'; | ||
import { useIntersectionObserver } from '@hooks/useIntersectionObserver'; | ||
import { usePostRequestInfo } from '@hooks/usePostRequestInfo'; | ||
|
||
import ErrorBoundary from '@pages/ErrorBoundary'; | ||
import { SORTING_OPTION, STATUS_OPTION } from '@pages/HomePage/constants'; | ||
import { PostSorting, PostStatus } from '@pages/HomePage/types'; | ||
|
||
import Select from '@components/common/Select'; | ||
import Skeleton from '@components/common/Skeleton'; | ||
import Post from '@components/post/Post'; | ||
|
||
import { PATH } from '@constants/path'; | ||
|
||
import EmptyPostList from '../EmptyPostList'; | ||
import PostListFetcher from '../PostListFetcher'; | ||
|
||
import * as S from './style'; | ||
|
||
export default function PostList() { | ||
const topButtonRef = useRef<HTMLButtonElement>(null); | ||
const { postType, postOptionalOption } = usePostRequestInfo(); | ||
const { loggedInfo } = useContext(AuthContext); | ||
const { targetRef, isIntersecting } = useIntersectionObserver({ | ||
root: null, | ||
rootMargin: '', | ||
thresholds: 0.1, | ||
}); | ||
|
||
const { postOption, setPostOption } = useContext(PostOptionContext); | ||
|
||
const { selectedOption: selectedStatusOption, handleOptionChange: handleStatusOptionChange } = | ||
useSelect<PostStatus>(postOption.status); | ||
const { selectedOption: selectedSortingOption, handleOptionChange: handleSortingOptionChange } = | ||
useSelect<PostSorting>(postOption.sorting); | ||
|
||
const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isPostListEmpty } = usePostList( | ||
{ | ||
postType, | ||
postSorting: selectedSortingOption, | ||
postStatus: selectedStatusOption, | ||
isLoggedIn: loggedInfo.isLoggedIn, | ||
}, | ||
postOptionalOption | ||
); | ||
|
||
const focusTopContent = () => { | ||
const { | ||
selectedOption: selectedStatusOption, | ||
handleOptionChange: handleStatusOptionChange, | ||
isSelectOpen: isStatusSelectOpen, | ||
toggleSelect: toggleStatusSelect, | ||
selectRef: statusSelectRef, | ||
handleCloseClick: handleStatusClose, | ||
} = useSelect<PostStatus>(postOption.status); | ||
const { | ||
selectedOption: selectedSortingOption, | ||
handleOptionChange: handleSortingOptionChange, | ||
isSelectOpen: isSortingSelectOpen, | ||
toggleSelect: toggleSortingSelect, | ||
selectRef: sortingSelectRef, | ||
handleCloseClick: handleSortingClose, | ||
} = useSelect<PostSorting>(postOption.sorting); | ||
|
||
const handleFocusTopContent = () => { | ||
if (!topButtonRef.current) return; | ||
|
||
topButtonRef.current.focus(); | ||
}; | ||
|
||
useEffect(() => { | ||
if (isIntersecting && hasNextPage) { | ||
fetchNextPage(); | ||
} | ||
}, [isIntersecting, fetchNextPage, hasNextPage]); | ||
|
||
return ( | ||
<S.Container> | ||
<S.Container | ||
onClick={(event: MouseEvent<HTMLDivElement>) => { | ||
handleStatusClose(event); | ||
handleSortingClose(event); | ||
}} | ||
> | ||
<button ref={topButtonRef} role="contentinfo" aria-label="최상단입니다" /> | ||
<S.SelectContainer> | ||
<S.SelectWrapper> | ||
<S.SelectWrapper ref={statusSelectRef}> | ||
<Select<PostStatus> | ||
isOpen={isStatusSelectOpen} | ||
toggleSelect={toggleStatusSelect} | ||
aria-label={`마감 여부로 게시글 정렬 선택, 현재 옵션은 ${STATUS_OPTION[selectedStatusOption]}`} | ||
handleOptionChange={(value: PostStatus) => { | ||
handleOptionChange={async (value: PostStatus) => { | ||
if (value === selectedStatusOption) return; | ||
|
||
setPostOption({ | ||
...postOption, | ||
status: value, | ||
}); | ||
|
||
handleStatusOptionChange(value); | ||
}} | ||
optionList={STATUS_OPTION} | ||
selectedOption={STATUS_OPTION[selectedStatusOption]} | ||
/> | ||
</S.SelectWrapper> | ||
<S.SelectWrapper> | ||
<S.SelectWrapper ref={sortingSelectRef}> | ||
<Select<PostSorting> | ||
isOpen={isSortingSelectOpen} | ||
toggleSelect={toggleSortingSelect} | ||
aria-label={`인기순/최신순으로 게시글 정렬 선택, 현재 옵션은 ${SORTING_OPTION[selectedSortingOption]}`} | ||
handleOptionChange={(value: PostSorting) => { | ||
if (value === selectedSortingOption) return; | ||
|
||
setPostOption({ | ||
...postOption, | ||
sorting: value, | ||
|
@@ -93,28 +92,18 @@ export default function PostList() { | |
/> | ||
</S.SelectWrapper> | ||
</S.SelectContainer> | ||
<ErrorBoundary hasIcon={true} hasRetryInteraction={true}> | ||
<Suspense | ||
fallback={ | ||
<S.SkeletonWrapper> | ||
<Skeleton isLarge={true} /> | ||
</S.SkeletonWrapper> | ||
} | ||
> | ||
<PostListFetcher handleFocusTopContent={handleFocusTopContent} /> | ||
</Suspense> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍👍 분리 너무 좋아요 |
||
</ErrorBoundary> | ||
<S.HiddenLink aria-label="게시글 작성 페이지로 이동" to={PATH.POST_WRITE} /> | ||
<S.PostListContainer> | ||
{isPostListEmpty && ( | ||
<EmptyPostList status={selectedStatusOption} keyword={postOptionalOption.keyword} /> | ||
)} | ||
{data?.pages.map((postListInfo, pageIndex) => ( | ||
<React.Fragment key={pageIndex}> | ||
{postListInfo.postList.map((post, index) => { | ||
if (index === 7) { | ||
return <Post key={post.postId} ref={targetRef} isPreview={true} postInfo={post} />; | ||
} | ||
|
||
return <Post key={post.postId} isPreview={true} postInfo={post} />; | ||
})} | ||
<li key={`${pageIndex}UserButton`}> | ||
<S.HiddenButton onClick={focusTopContent} aria-label="스크롤 맨 위로가기" /> | ||
<S.HiddenLink aria-label="게시글 작성 페이지로 이동" to={PATH.POST_WRITE} /> | ||
</li> | ||
</React.Fragment> | ||
))} | ||
{isFetchingNextPage && <Skeleton isLarge={false} />} | ||
</S.PostListContainer> | ||
</S.Container> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
👍👍👍