-
Notifications
You must be signed in to change notification settings - Fork 10
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
[4주차] 최지원 미션 제출합니다. #15
base: master
Are you sure you want to change the base?
Conversation
src/components/ChatRoom/InputBox.tsx
Outdated
<textarea | ||
value={inputText} | ||
onChange={handleChange} | ||
onKeyDown={handleEnterSubmit} |
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.
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.
퉁퉁이..
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.
진짜 하나하나 고민하고 추가하고 고생한게 느껴지는 과제였어요!! 많이 배우고 가요!! 하나하나 더 꼼꼼히 보고 싶었는데 시간상 이슈로ㅠㅠㅠ
import { chattingState, userState } from "../../recoil/atom"; | ||
import { useEffect, useState } from "react"; | ||
|
||
import userData from "../../data/UserData.json"; |
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.
파일 경로가 점점 길어질 경우에는 미리 절대경로를 설정해서 사용하는 걸 추천드려요!
setSearchInput(e.target.value); | ||
}; | ||
|
||
// 상단 고정 기능 |
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.
요거는 머를 고정한 건지 알 수 있을까용?
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 filteredFollowers = chattings |
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.
요 부분이 채팅을 정렬하는 부분같은데, 매번 렌더링되는게 조금 무거울 수도 있으니까, useMemo등으로 묶어주시는 건 어떨까용?
<div className="flex w-full flex-row gap-2 py-2"> | ||
<img | ||
className="h-14 w-14 flex-shrink-0 rounded-full" | ||
src={require("../../assets/images/" + follower.profileImg + ".svg")} |
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.
요거 경로를 미리 앞에서 선언하고 가져오는 건 어떨까요!!
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.
require을 쓰지 않으면 에러가 나서 감싸느라 요런 식으로 썼는데 앞에서 선언하는 방식도 시도해보겠습니다!
className="flex flex-grow cursor-pointer flex-col" | ||
> | ||
<div className="flex flex-row items-center"> | ||
<span className="text-[0.8125rem] font-semibold tracking-tighter"> |
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.
이런 부분은 시멘틱 태그를 사용해서 p
태그로 해주시면 더 좋을 것 같다는 그냥 개인적인 생각입니다!!!
)} | ||
|
||
{selectedEmotion && ( | ||
<> |
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.
요 빈태그는 필요 없을 거 같아용!
{isLastChat ? ( | ||
<img | ||
className="h-7 w-7 rounded-full" | ||
src={require("../../assets/images/" + profileImg + ".svg")} //props로 넘겨온 상대경로는 깨짐 |
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.
src={require("../../assets/images/" + profileImg + ".svg")} //props로 넘겨온 상대경로는 깨짐 | |
src={require(`../../assets/images/${profileImg}.svg`)} |
{isImageMessage ? ( | ||
// 이미지 메시지인 경우 | ||
<img | ||
src={message} | ||
alt="sent image" | ||
className={`ml-2 mr-auto w-[10.0625rem] rounded-[1.25rem] ${isLastChat ? "mb-[0.3125rem]" : ""}`} | ||
/> | ||
) : ( | ||
// 텍스트 메시지인 경우 |
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.
{isImageMessage ? ( | |
// 이미지 메시지인 경우 | |
<img | |
src={message} | |
alt="sent image" | |
className={`ml-2 mr-auto w-[10.0625rem] rounded-[1.25rem] ${isLastChat ? "mb-[0.3125rem]" : ""}`} | |
/> | |
) : ( | |
// 텍스트 메시지인 경우 | |
//상단에 | |
const renderMessageContent = () => { | |
if (isImageMessage) { | |
return ( | |
<img | |
src={message} | |
alt="sent image" | |
className={`ml-2 mr-auto w-[10.0625rem] rounded-[1.25rem] ${isLastChat ? "mb-[0.3125rem]" : ""}`} | |
/> | |
); | |
} | |
return ( | |
<div className="ml-2 mr-auto inline-flex max-w-[13.375rem] items-center break-all rounded-[1.25rem] bg-Chat_BG px-2.5 py-2 text-[0.9375rem] tracking-tighter text-white"> | |
{message} | |
</div> | |
); | |
}; | |
//사용 | |
{renderMessageContent ()} | |
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.
조건부로 코드 길어지는 부분이 많았는데 다음엔 함수화 해서 써보겠습니다🥹💫
|
||
return ( | ||
<> | ||
<div className="mt-[1.31rem] flex flex-col px-[0.88rem]"> |
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.
요런거 시멘틱 태그 살려주면 좋을 거 같아요 파일 전ㅊㅔ적으로!
<div className="flex w-[7.75rem] items-center justify-center text-[0.8125rem] font-semibold text-Gray500"> | ||
3 following |
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.
이런 부분도 겹치는 부분 같아서요!
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.
이번 과제하느라고 고생많으셨습니다! 추가 기능구현을 하신 부분이 인상깊습니다! 지원님의 노력이 많이 돋보였습니다~!
className="ml-[4.35rem] mt-[0.31rem] h-0.5 w-[4.011rem] bg-Gray900 transition-transform duration-300" | ||
style={{ | ||
transform: | ||
currentTab === 0 ? "translateX(0)" : "translateX(10.65rem)", | ||
}} | ||
></div> | ||
{/* <div>{tab[currentTab].content}</div> */} | ||
<div className="w-full overflow-hidden"> | ||
<div | ||
className="transition-transform duration-300" | ||
style={{ | ||
transform: `translateX(-${currentTab * 50}%)`, | ||
display: "flex", | ||
width: "200%", | ||
}} | ||
> |
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.
슬라이더 애니메이션으로 더 완성도 있어 보여요! framer motion이라는 라이브러리를 사용하면 애니메이션 사용이 더 편리해지더라구요! 참고부탁드려요
<PictureIcon | ||
onClick={handlePictureIconClick} | ||
className="cursor-pointer" | ||
/> | ||
<input | ||
type="file" | ||
accept="image/*" | ||
ref={fileInputRef} | ||
onChange={handleImageUpload} | ||
className="hidden" | ||
/> |
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.
저는 이번에 추가 기능 구현을 못했는데, 지원님은 이미지 전송기능 추가해주셨네요!! 👍
localStorage.setItem("pinnedChatIds", JSON.stringify(pinnedChatIds)); | ||
}, [pinnedChatIds]); | ||
|
||
const handlePinToggle = (id: number | undefined) => { |
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 handlePinToggle = (id: number | undefined) => { | |
const handlePinToggle = useCallback((id: number | undefined) => { ... }, []); | |
useCallback을 통한 함수 메모이제이션을 하면 최적화에 좋을 거 같습니다!
💌 구현물
default.mp4
(화질이 살짝 구린 점.. 양해부탁드립니다🥺)
🎨 피그마
💁♀️ 구현기능
(기본)
(추가)
💦 어려웠던 점 및 느낀점
타입스크립트를 써본지 2주차인데, 아직 적응이 되지 않아 타입관련 에러가 정말 자주 났습니다.. props를 전달해주면서 interface로 인자와 타입을 추가해주는 것에는 익숙해졌으나 undefined가 들어갈 수 있는 곳/없는 곳 등에 유의하며 정의해주고, 값을 넣어주고 (특히 id 유의..), 혹은 undefined가 아닐 때라는 조건부를 처리해주는 과정이 많은 에러를 마주해야 해서 까다로웠습니다.
이미지 전송에서도 많은 난관이 있었습니다. (살짝 구구절절.. 길어져서 토글 열면 이어집니다ヾ(°∇°*)
더보기
핀 기능은 배열로 chat id들을 추가해주는 것은 간단했지만 고정하는 순서에 따라 상단에 최신으로 업데이트 되도록 정렬하는 계산을 처리해주어야 했습니다. 참고로 핀은 피그마 디자인에 없었는데 프론트 추가 구현기능으로 있어서 디자이너분께 연락드리기엔.. 과제 마감까지 얼마 남지 않아 제가 임의로 넣어보았습니다.. (다음부터는 꼭 미리미리 해서 디자이너분께 여쭤보고 상의를 할 수 있도록 하겠습니다..🥲🥲)
🔑 Key Questions
( 1 ) React Router의 동적 라우팅(Dynamic Routing)이란 무엇이며, 언제 사용하나요?
동적 라우팅은 url 전체 형태를 미리 정의하지 않고 특정 규칙을 정의한 후, 규칙에 부합한 url이 있을 때 해당 element가 보여지는 방식을 말한다. 이와 반대되는 개념인 정적 라우팅은 라우터 컴포넌트에서 사용할 경로와 해당 경로로 접속할 시 보여줄 컴포넌트를 미리 정의하는 방식이다. 주로 규모가 크고 복잡한 애플리케이션에서 경로를 미리 설정하기 어려울 경우 (ex. 목록이라면 리스트 페이지와 각 상세페이지를 모두 각각 라우팅하는 것은 비효율적) 에 동적라우팅을 사용한다.
추가로, useParams hook을 사용하면 path parameter을 가져와 사용할 수 있다. state처럼 params의 값이 변함에 따라 컴포넌트를 리렌더링할 수 있다.
( 2 ) 네트워크 속도가 느린 환경에서 사용자 경험을 개선하기 위해 사용할 수 있는 UI/UX 디자인 전략과 기술적 최적화 방법은 무엇인가요?
<UI/UX 디자인 전략>
<기술적 최적화 방법>
( 3 ) React에서 useState와 useReducer를 활용한 지역 상태 관리와 Context API 및 전역 상태 관리 라이브러리의 차이점을 설명하세요.
지역 상태: 특정 컴포넌트 안에서만 관리되는 상태로, 다른 컴포넌트들과 데이터를 공유하지 않는다.
전역 상태: 프로젝트 전체에 영향을 끼치는 상태