Conversation
hyesngy
left a comment
There was a problem hiding this comment.
10주차 워크북까지 정말 긴 여정이었습니다.
그동안 모두 고생 많으셨습니다! 👏🏻👏🏻👏🏻 짧지 않은 기간동안 의미 있는 시간이 되었기를 바랍니다.
이제 기본 워크북은 모두 완주하셨지만, 11-12주차 워크북도 도전해보시길 추천드립니다! 11주차에서는 Vercel을 활용한 배포와 CI/CD 구성을 다루고, 12주차에서는 WebSocket을 이용한 실시간 통신과 Cypress를 활용한 E2E 테스트를 다룹니다.
앞으로도 꾸준히 학습하고 성장하시길 응원하며, 데모데이까지 화이팅 입니다! 👍🏻👍🏻👍🏻
| return ( | ||
| <> | ||
| <li key={movie.id} onClick={handleClick} className="relative w-32 group aspect-[2/3] rounded-md overflow-hidden"> | ||
| {/* <h3>{movie.title}</h3> */} | ||
| <img | ||
| src={`${imgURL}${movie.poster_path}`} | ||
| alt="포스터" | ||
| className="w-full h-full object-cover block group-hover:blur-md" | ||
| /> | ||
|
|
||
|
|
||
| <div | ||
| className="absolute top-0 left-0 w-full h-full opacity-0 group-hover:opacity-100 | ||
| text-sm/7 text-white flex flex-col items-center justify-center p-4" | ||
| > | ||
| <h3 className="text-sm">{movie.title}</h3> | ||
| <div className="text-xs overflow-hidden text-ellipsis" | ||
| style={{ | ||
| display: "-webkit-box", | ||
| WebkitLineClamp: 3, | ||
| WebkitBoxOrient: "vertical" | ||
| }}>{movie.overview}</div> | ||
| </div> | ||
| </li> | ||
|
|
||
| <DetailModal/> | ||
| </> | ||
|
|
||
| ) |
| <div className="flex-1"> | ||
| <label className="flex items-center gap-2 text-sm font-semibold mb-1"> | ||
| <GrSettingsOption /> | ||
| 옵션 | ||
| </label> | ||
| <div className="flex items-center gap-2"> | ||
| <input | ||
| type="checkbox" | ||
| id="adult" | ||
| checked={includeAdult} | ||
| onChange={(e) => setIncludeAdult(e.target.checked)} | ||
| /> | ||
| <label htmlFor="adult" className="text-sm"> | ||
| 성인 콘텐츠 표시 | ||
| </label> | ||
| </div> | ||
| </div> | ||
| </div> | ||
|
|
||
|
|
||
|
|
||
| <div> | ||
| <label className="flex items-center gap-2 text-sm font-semibold mb-1"> | ||
| <FaGlobe /> | ||
| 언어 | ||
| </label> | ||
| <select | ||
| className="w-full border border-gray-300 rounded px-3 py-2 focus:outline-none" | ||
| value={language} | ||
| onChange={(e) => setLanguage(e.target.value)} | ||
| > | ||
|
|
||
| <option value="ko">한국어</option> | ||
| <option value="en">영어</option> | ||
| <option value="ja">일본어</option> | ||
| </select> | ||
| </div> |
There was a problem hiding this comment.
현재 SearchComp에서 language와 includeAdult 상태가 변경될 때마다 전체 컴포넌트가 리렌더링됩니다. 이 부분을 useCallback으로 최적화하고, 상태 변경을 최소화하면 검색 성능이 향상될 것 같습니다. 또한 form 제출 시에만 실제 검색이 이루어지도록 로직을 분리해보면 어떨까요?
| <select | ||
| className="w-full border border-gray-300 rounded px-3 py-2 focus:outline-none" | ||
| value={language} | ||
| onChange={(e) => setLanguage(e.target.value)} | ||
| > | ||
|
|
||
| <option value="ko">한국어</option> | ||
| <option value="en">영어</option> | ||
| <option value="ja">일본어</option> | ||
| </select> |
There was a problem hiding this comment.
현재 select에서 "ko", "en", "ja" 값을 사용하지만 실제 API 호출에서는 "ko-KR" 형태를 사용하여 불일치가 발생합니다. 언어 코드 매핑을 일관성 있게 처리하면 검색 결과의 정확성이 향상될 것 같습니다!
There was a problem hiding this comment.
🚀Challenge 미션에 따라 프로젝트 전체의 성능 최적화나 UX 개선에도 도전해보세요! 코드 품질 측면에서도 중복 제거, 책임 분리, 예외 처리 개선 등을 통해 가독성과 유지보수성이 좋은 코드로 리팩토링 해보면 어떨까요 😊

📝 미션 번호
10주차 Misson 1
📋 구현 사항
10주차 미션 1
📎 스크린샷
2025-06-01.012735.mp4
✅ 체크리스트
🤔 질문 사항