Skip to content
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

1조 React 유튜브 프로젝트 제출 #5

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

1조 React 유튜브 프로젝트 제출 #5

wants to merge 1 commit into from

Conversation

05Castle
Copy link

@05Castle 05Castle commented Mar 17, 2023

React 유튜브 토이 프로젝트

사용 기술

조원

권오성
김철균
이화정

역할 분담

권오성

  • 헤더
  • 사이드바
  • 관련 동영상
  • 검색 페이지

김철균

  • 메인 동영상 리스트
  • 동영상 카드

이화정

  • 동영상 페이지
  • 동영상 정보
  • 채널 정보
  • 댓글 정보

아쉬운 점 & 어려웠던 점

권오성
팀 전체적으로 코드 통일성이 부족한 점과 컴포넌트 구조를 효율적으로 재활용하지 못한 점이 아쉽습니다. 무엇보다 원하는만큼 기한내에 완성하지 못한 것이 아쉽습니다.
통일감 있는 코드를 구성하기 위해 팀 작업 시작할 때 무엇을 어떻게 정하는 지가 어려웠습니다.
이미 구성된 각자의 코드를 어떻게 통일감있게 리팩토링 할 것인지 그 방법이 궁금합니다.

김철균
메인페이지에서 유튜브처럼 이미지 호버시 미리보기 영상을 넣는데 유튜브 예시가 많이 없어 어려움이 있었습니다.

이화정
최초 접속시 localStorage 값 여부 조건에 따라 api 데이터를 호출을 하고싶었는데 에러로 인해 사용 못한점이 아쉽습니다.
프로젝트를 하며 상태관리와 데이터 패칭 라이브러리 적용하지 못한 아쉬움이 남았습니다. 어디든 적용 가능하도록 더욱 공부해야겠다는 생각이 들었습니다.

},
})
return response.data.items
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

어떤 api들은 axios 폴더로 관리되고 어떤 api들은 컴포넌트에서 호출되더라구욤..?
통일성이 있으면 좋겠죠~?
아직 도입되진 않았지만 axios에 interceptor를 넣게 된다면 axios 코드가 되게 길어질거에욤~~
그래서 axios랑 query들도 파일 분리를 하면 좋겠네요 !

import { useNavigate, Link, useLocation } from 'react-router-dom'

function Header() {
const [isOpen, setIsOpen] = useRecoilState(navToggleState) //eslint-disable-line no-unused-vars
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import { useSetRecoilState } from 'recoil'
const setIsOpen = useSetRecoilState(navToggleState)

no-unused-vars를 피하기 위해서라면요!

import { MenuSection, MenuListWrapper, MenuItemWrapper } from './style'

function SideBar() {
const open = useRecoilValue(navToggleState)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const MenuList = [
	{
		key: 0,
		className: '',
		list: [
			{
				link: '/',
				text: '홈',
				svg: <HomeSvg />,
			},
			{
				link: '/',
				text: 'Shorts',
				svg: <ShortsSvg />,
			},
			{
				link: '/',
				text: '구독',
				svg: <SubscribeSvg />,
			},
			{
				link: '/',
				text: 'Originals',
				svg: <OriginalSvg />,
			},
			{
				link: '/',
				text: 'YouTube Music',
				svg: <MusicSvg />,
			},
		],
	},
	{
		key: 1,
		className: 'playListMenu',
		list: [
			{
				link: '/',
				text: '보관한',
				svg: <StoreSvg />,
			},
			{
				link: '/',
				text: '시청기록',
				svg: <WatchLog />,
			},
			{
				link: '/',
				text: '내 동영상',
				svg: <MyVideo />,
			},
			{
				link: '/',
				text: '나중에 볼 동영상',
				svg: <LaterVideo />,
			},
		],
	},
	{
		key: 2,
		className: 'optionMenu',
		list: [
			{
				link: '/',
				text: '설정',
				svg: <SettingSvg />,
			},
			{
				link: '/',
				text: '신고기록',
				svg: <RefortSvg />,
			},
			{
				link: '/',
				text: '고객센터',
				svg: <CustomerSvg />,
			},
			{
				link: '/',
				text: '의견 보내기',
				svg: <SendOpinion />,
			},
		],
	},
]

</MenuItemWrapper>
</NavLink>
</li>
</MenuListWrapper>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

		{MenuList.map((v) => {
			return (
				<MenuListWrapper key={v.key} className={v.className}>
					{v.list.map((v, idx) => {
						return (
							<li key={idx}>
								<NavLink to={v.link}>
									<MenuItemWrapper>
										{v.svg}
										{v.text}
									</MenuItemWrapper>
								</NavLink>
							</li>
						)
					})}
				</MenuListWrapper>
			)
		})}

import { NavLink } from 'react-router-dom'
import { useRecoilValue } from 'recoil'
import { navToggleState } from '../../atom'
import { MenuSection, MenuListWrapper, MenuItemWrapper } from './style'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// section 1
import HomeSvg from '@svg/HomeSvg'
import MusicSvg from '@svg/MusicSvg'
import OriginalSvg from '@svg/OriginalSvg'
import ShortsSvg from '@svg/ShortsSvg'
import SubscribeSvg from '@svg/SubscribeSvg'

// section 2
import LaterVideo from '@svg/LaterVideo'
import MyVideo from '@svg/MyVideo'
import StoreSvg from '@svg/StoreSvg'
import WatchLog from '@svg/WatchLog'

// section 3
import CustomerSvg from '@svg/CustomerSvg'
import RefortSvg from '@svg/RefortSvg'
import SendOpinion from '@svg/SendOpinion'
import SettingSvg from '@svg/SettingSvg'

const OptionBtnContainer = styled.div`
display: flex;
gap: 4px;
`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

어떤 스타일 태그는 파일을 분리하고 어떤 스타일 태그는 파일을 합쳤을까욤~?
그 기준이 있을까요?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

갑작스레 진행한 플젝이라 팀원들끼리 규칙을 따로 정하지 못하고 각자 스타일대로 작성하다보니 이렇게 되었습니다😅
협업 규칙이 많이 중요하단 것을 느꼈습니다!

<div className="filterItem">게임</div>
<div className="filterItem">수학</div>
</div>
</VideoCard>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const filterList = ['전체', ' 실시간', '음악', '뉴스', '게임', '수학']
/* ... */


{filterList.map((v) => {
return (

{v}

)
})}


const Main = () => {
const [playlist, setPlaylist] = useState([])
useEffect(() => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

react hook으로 쿼리를 fetch하는건 가급적 선택하지 않았으면 하는 옵션 중 하나입니다.
depdencyArray를 빈 배열로 줘서 컴포넌트가 랜더링할때 한번만 실행되도록 했지만,
다른 이유(ex. 부모컴포넌트의 리랜더링)에 의해서 쿼리가 다시 패치될 가능성이 있습니다.
cloud servide에서 query call === cost!! 제가 드리는 대안 중 하나는 react-query입니다.

setPlaylist(res.data.items)
})
.catch(() => {})
}, [])
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const { data, isLoading, isSuccess } = useQuery(
	['getPlayList'],
	() => {
		return axios.get(
			'https://www.googleapis.com/youtube/v3/videos?part=snippet&chart=mostPopular&maxResults=4&key=AIzaSyCZmSMmjRPzSl8o8u6KUIR4Nf8J2v1DJGs'
		)
	},
	{
		select: (res) => {
			return res?.data?.items
		},
	}
)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

물론 api파일은 분리하면 좋겠죠~?

</div>
)
})}
</div>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

			<div className="videoComponent">
				{isLoading ? (
					<p>isLoading...</p>
				) : (
					<>
						{data &&
							isSuccess &&
							data.map((i, idx) => {
								return (
									<div className="playlist" key={idx}>
										<Link to={'/video/' + i.id}>
											<img src={i.snippet.thumbnails.high['url']} alt="" />
										</Link>
										<div>
											<Link to={'/video/' + i.id}>
												<h1>{i.snippet.localized['title']}</h1>
											</Link>
										</div>
									</div>
								)
							})}
					</>
				)}
			</div>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants